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分支测试下,看对应的工作流是否跑通。

相关推荐
崔庆才丨静觅18 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606118 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了18 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅18 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅19 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅19 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment19 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅20 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊20 小时前
jwt介绍
前端
爱敲代码的小鱼20 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax