Skip to content
前端项目自动化部署流水线

一、 环境背景与架构设计

在本项目中,我们构建了一套基于 GitHub Actions 和 阿里云容器镜像服务(ACR)的自动化部署流程(CI/CD)。

1. 核心架构

  • 代码仓库:GitHub
  • 自动化工具:GitHub Actions
  • 镜像仓库:阿里云容器镜像服务(个人版)
  • 部署环境:阿里云 ECS(Ubuntu/CentOS),运行 Docker Compose
  • 自动更新:Watchtower 容器,负责监控镜像变动并重启服务

2. 技术栈

  • 前端:Vite + Vue(打包为静态资源)
  • 网关/服务器:Nginx(容器化部署)
  • 后端:Spring Boot(端口 8084,Context-Path: /my-server)

二、 自动化部署标准步骤

1. 编写 Dockerfile (前端)

由于 GitHub 所在的海外环境拉取 Docker Hub 镜像常遇到限流,建议在 GitHub Actions 中配置登录后再进行构建。

dockerfile
FROM nginx:stable-alpine
# 移除默认配置并复制自定义配置与打包后的静态文件
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/
COPY dist/ /usr/share/nginx/html/pjone/
EXPOSE 80

2. 配置 GitHub Actions 工作流

在项目根目录 .github/workflows/frontend.yml 中配置双登录策略:先登录 Docker Hub 避开限流,再登录 阿里云 推送镜像。

yaml
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Login to Ali-Registry
        run: docker login --username=${{ secrets.ALI_USERNAME }} --password=${{ secrets.ALI_PASSWORD }} ${{ secrets.ALI_REGISTRY }}

      - name: Build and Push
        run: |
          IMAGE_NAME=${{ secrets.ALI_REGISTRY }}/your-space/my-web:latest
          docker build -t $IMAGE_NAME .
          docker push $IMAGE_NAME

3. 服务器 Docker Compose 配置

配置 Watchtower 实现无人值守自动更新,核心在于挂载认证文件。

yaml
  web:
    image: registry.cn-hangzhou.aliyuncs.com/your-space/my-web:latest
    container_name: my-web
    restart: always
    ports:
      - "8081:80"

  watchtower:
    image: containrrr/watchtower
    container_name: my-watchtower
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /root/.docker/config.json:/config.json:ro
    command: --interval 30 --cleanup

三、 实战遇到的问题汇总

1. Nginx 转发导致后端 404

  • 现象:Postman 直接访问后端端口成功,但通过 Nginx 转发后报 404。
  • 原因proxy_pass 路径拼接逻辑错误。在配置中使用了 proxy_pass http://server:8084/;(带末尾斜杠),导致 Nginx 剥离了 location 匹配的前缀,而后端接口恰好需要该前缀。
  • 报错日志:Nginx error log 显示找不到请求路径或后端 Tomcat 抛出 404 页面。

2. Docker Hub 镜像拉取限流 (429 Too Many Requests)

  • 现象:GitHub Actions 在执行 docker build 时,拉取 FROM nginx 失败。
  • 原因:GitHub Actions 公用 IP 被 Docker Hub 判定为匿名请求过多,触发限流。

3. Watchtower 无法自动更新 (Up 2 days)

  • 现象:Actions 显示成功推送到阿里云,但服务器容器启动时间未更新。
  • 原因:Watchtower 运行在隔离容器内,没有宿主机的阿里云登录凭证(config.json),无法拉取私有仓库镜像。

四、 最终解决方案

1. 修正 Nginx 转发配置

取消 proxy_pass 目标地址末尾的斜杠,实现路径完整透传。

nginx
location /my-server/ {
    proxy_pass http://server:8084; # 去掉末尾斜杠
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

2. 实施 Docker Hub 登录策略

在 GitHub 项目 Settings 中添加 DOCKERHUB_USERNAMEDOCKERHUB_TOKEN。在 Workflow 中增加登录步骤,确保以身份校验状态拉取基础镜像,彻底规避 429 报错。

3. 挂载 Watchtower 认证凭证

在服务器执行一次 docker login 后,将产生的 /root/.docker/config.json 挂载至 Watchtower 容器内部的 /config.json 路径,并赋予只读权限。这是实现私有镜像自动更新的关键步骤。


通过以上方案,系统实现了从代码推送、自动化镜像构建、私有仓库托管到服务器无感自动更新的完整闭环。