Github Action + docker 实现自动化部署

当一个项目开发完,需要部署到服务器时,如果直接在服务器上拉取代码、打包运行,就需要服务器环境与本地保持一致,不然就会出现本地能跑服务器跑不了的情况,想想就让人头疼。

使用docker部署就不需要再为环境考虑了,还支持版本管理,并且还有docker-compose等编排工具提供多容器的统一管理。使用docker部署仅需三步:

  1. 打包镜像
  2. 发布镜像
  3. 拉取镜像并执行

下面就以一个前端Vue项目为例,用 Github Actoin 来实现docker的自动部署流程。

编写Dockerfile

首先要为项目编写Dockerfile,前端通常使用nginx进行部署:

bash 复制代码
FROM node:18.20-alpine3.21 as build-stage

WORKDIR /app

COPY package.json .

# 配置npm和pnpm
RUN npm config set registry https://registry.npmmirror.com/
RUN npm install pnpm -g
RUN pnpm config set registry https://registry.npmmirror.com/
RUN pnpm install

COPY . .

RUN pnpm build

# production stage
FROM nginx:stable as production-stage

COPY --from=build-stage /app/dist /usr/share/nginx/html

EXPOSE 443

CMD ["nginx", "-g", "daemon off;"]

这里采用分阶段打包,只需要将dist打进镜像,放入到nginx的资源目录下,暴露443端口(如果不是https就配置80端口)并设置nginx启动指令。Dockerfile的编写很简单,直接交给GPT生成即可。

编写发布docker脚本(可选)

镜像仓库的地址可能会比较长,所以打包、发布的指令也会很长,写个shell脚本自动执行这两个步骤比较省事:

bash 复制代码
# 先构建镜像并打标签
docker build -t registry.xxx.com/xxx/xxx:latest . || {
  echo "Docker构建失败"
  exit 1
}

# 检查镜像是否存在
docker images | grep registry.xxx.com/xxx/xxx:latest || {
  echo "构建的镜像不存在"
  exit 1
}

# 推送镜像
docker push registry.xxx.com/xxx/xxx:latest || {
  echo "Docker推送失败"
  exit 1
}

仓库地址替换为最终要上传的镜像仓库地址,例如dockerhub或阿里云镜像仓库等。

编写workflow

要触发github action只需要在项目根目录下 .github/workflows 文件夹里添加对应的流程配置文件,这里我们添加一个deploy.yml配置:

yml 复制代码
name: Deploy Frontend to Server

on:
  push:
    branches:
      - release # 当代码推送到 release 分支时触发

jobs:
  build-and-push:
    name: Build and Push Docker Image
    runs-on: ubuntu-latest # 使用最新的 Ubuntu Runner
    steps:
      - name: Checkout code
        uses: actions/checkout@v4 # 检出你的代码

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3 # 设置 Docker Buildx 以便构建镜像

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: registry.xxx.com # 你的镜像仓库地址
          username: ${{ secrets.DOCKER_USERNAME }} # 从 GitHub Secrets 读取 Docker 用户名
          password: ${{ secrets.DOCKER_PASSWORD }} # 从 GitHub Secrets 读取 Docker 密码

      - name: Build and push Docker image using deploy.sh
        run: |
          chmod +x ./deploy.sh # 赋予 deploy.sh 执行权限
          ./deploy.sh # 执行构建和推送脚本
        shell: bash # 指定使用 bash shell

  deploy-remote:
    name: Deploy to Remote Server
    runs-on: ubuntu-latest
    needs: build-and-push # 依赖于 build-and-push 任务成功完成
    steps:
      - name: Deploy to Remote Server via SSH
        uses: appleboy/ssh-action@master # 使用社区提供的 SSH Action
        with:
          host: ${{ secrets.REMOTE_HOST }} # 从 GitHub Secrets 读取远程服务器 IP 或主机名
          username: ${{ secrets.REMOTE_USER }} # 从 GitHub Secrets 读取远程服务器登录用户名
          key: ${{ secrets.SSH_PRIVATE_KEY }} # 从 GitHub Secrets 读取 SSH 私钥
          script: |
            echo "Connecting to remote server..."
            # 进入 docker-compose.yml 文件所在的目录
            cd /root/deploy
            echo "Pulling latest image..."
            docker-compose pull frontend || { echo "Docker Compose pull failed"; exit 1; }
            echo "Starting container..."
            docker-compose up -d --no-deps frontend || { echo "Docker Compose up failed"; exit 1; }
            echo "Deployment successful!"

示例中使用docker-compose管理前后端docker服务,需要配置docker-compose.yml。也可以直接使用docker管理单个容器。

例如私钥、密码等重要信息不要明文写在配置中,github action提供secrets变量存储,将重要信息保存在这里,通过secrets访问:

ssl登录服务器有两种方式,可以通过密码登录,也可以通过密钥登录。推荐使用密钥登录,明文保存密码不太安全。

密钥登录需要通过ssh-keygen生成一个密钥对,公钥存放到服务 ~/.ssh/authorized_keys 文件中(一行一个密钥),没有这个文件就自己创建一个,私钥就存放在secrets中。这个配置是不是似曾相识,其实就是本地与github通讯配置的ssh key,所以这里可以复用已有的ssh key,将公钥 ~/.ssh/id_dsa.pub 内容复制到上面提到的authorized_keys文件中,私钥 ~/.ssh/id_dsa 内容复制粘贴到secrets.SSH_PRIVATE_KEY中即可。

到这里配置就结束了,提交点内容到release分支测试下,看对应的工作流是否跑通。

相关推荐
10年前端老司机4 分钟前
React 受控组件和非受控组件区别和使用场景
前端·javascript·react.js
夏晚星4 分钟前
vue实现微信聊天emoji表情
前端·javascript
停止重构6 分钟前
【方案】前端UI布局的绝技,响应式布局,多端适配
前端·网页布局·响应式布局·grid布局·网页适配多端
極光未晚7 分钟前
TypeScript在前端项目中的那些事儿:不止于类型的守护者
前端·javascript·typescript
ze_juejin8 分钟前
Vue3 + Vite + Ant Design Vue + Axios + Pinia 脚手架搭建
前端·vue.js
lichenyang45310 分钟前
React项目(移动app)
前端
用户618482402195111 分钟前
Vue-library-start,一个基于Vite的vue组件库开发模板
前端
美团技术团队22 分钟前
报名 | 美团技术沙龙第86期:多业务场景下,美团如何做性能优化
前端
Rrvive1 小时前
localhost 和 127.0.0.1 的核心区别
前端
蓝倾1 小时前
如何使用Python通过API接口批量抓取小红书笔记评论?
前端·后端·api