前端CI/CD 流程

企业级 Vue3 + Docker + GitHub Actions + PM2 + Nginx CI/CD 流程 完整落地模板化,包含:

  • 项目骨架
  • Dockerfile + nginx.conf
  • PM2 ecosystem
  • GitHub Actions ci-cd.yml
  • ESLint + Prettier + commitlint
  • 多环境配置(dev/test/prod)
  • 敏感文件保护 + MR 审批

下面是详细文件结构和内容。


一、项目目录结构

复制代码
vue3-project/
├── src/
│   ├── main.ts
│   ├── App.vue
│   └── components/
├── public/
├── Dockerfile
├── nginx.conf
├── ecosystem.config.js
├── .github/
│   └── workflows/
│       └── ci-cd.yml
├── package.json
├── tsconfig.json
├── .eslintrc.js
├── .prettierrc
├── .commitlintrc.js
├── .env.development
├── .env.test
├── .env.production
└── README.md

二、Dockerfile

dockerfile 复制代码
# Stage 1: Build
FROM node:18 AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install -g pnpm
RUN pnpm install
COPY . .
RUN pnpm build

# Stage 2: Production
FROM nginx:stable-alpine
RUN rm -rf /etc/nginx/conf.d/*
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

三、nginx.conf

nginx 复制代码
server {
  listen 80;
  server_name localhost;
  root /usr/share/nginx/html;
  index index.html;

  location / {
    try_files $uri $uri/ /index.html;
  }

  location /api/ {
    proxy_pass http://127.0.0.1:3000/;
    proxy_set_header Host $host;
  }
}

四、PM2 ecosystem.config.js

js 复制代码
module.exports = {
  apps: [
    {
      name: "vue3-client",
      script: "docker",
      args: "run -p 80:80 --name vue3-client --rm registry.com/vue3-client:latest",
      exec_mode: "fork",
      autorestart: true
    }
  ]
};

五、GitHub Actions CI/CD .github/workflows/ci-cd.yml

yaml 复制代码
name: Vue3 CI/CD Pipeline

on:
  push:
    branches:
      - main
      - develop
      - release/*
  pull_request:

env:
  REGISTRY: registry.com
  IMAGE_NAME: vue3-client
  DOCKER_TAG: latest

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install pnpm
        run: npm install -g pnpm

      - name: Install dependencies
        run: pnpm install

      - name: Lint code
        run: pnpm lint

      - name: Type check
        run: pnpm type-check

      - name: Build Vue project
        run: pnpm build

      - name: Login Docker registry
        run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

      - name: Build Docker image
        run: docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DOCKER_TAG }} .

      - name: Push Docker image
        run: docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.DOCKER_TAG }}

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: SSH Deploy
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_KEY }}
          script: |
            docker pull registry.com/vue3-client:latest
            pm2 delete vue3-client || true
            pm2 start ecosystem.config.js
            pm2 save
  • develop → 自动部署测试环境
  • release/* → 自动部署预发
  • main → 手动触发生产部署

六、ESLint + Prettier + Commitlint

.eslintrc.js

js 复制代码
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: ["plugin:vue/vue3-essential", "eslint:recommended", "prettier"],
  parserOptions: {
    ecmaVersion: 2020,
  },
  rules: {
    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off"
  },
};

.prettierrc

json 复制代码
{
  "semi": true,
  "singleQuote": true,
  "printWidth": 100,
  "tabWidth": 2,
  "trailingComma": "es5"
}

.commitlintrc.js

js 复制代码
module.exports = { extends: ["@commitlint/config-conventional"] };

七、多环境配置

.env.development

复制代码
VITE_API_URL=https://dev.example.com/api

.env.test

复制代码
VITE_API_URL=https://test.example.com/api

.env.production

复制代码
VITE_API_URL=https://api.example.com

在 vite.config.ts 中根据 mode 动态加载。


八、敏感文件保护

  1. .github/workflows/ci-cd.yml 中可以加校验敏感文件:
bash 复制代码
CHANGED=$(git diff --name-only origin/$GITHUB_BASE_REF)
PROTECTED="Dockerfile|nginx.conf|ecosystem.config.js"

if echo "$CHANGED" | grep -E "$PROTECTED"; then
  echo "❌ Protected files modified!"
  exit 1
fi
  1. GitHub 分支保护:
  • main → Require pull request reviews → 必须审批
  • develop → Optional auto deploy

九、完整企业 CI/CD 流程

复制代码
开发 push develop/release/main
      ↓
GitHub Actions CI
  1. 安装依赖
  2. ESLint / TypeCheck
  3. 构建 Vue3
  4. 检查是否修改敏感文件(保护机制)
      ↓
MR 审核(CODEOWNERS 自动指派)
      ↓
审核通过 → 合并到 develop
 	↓
  5. Docker build + push
      ↓
CD 自动部署
  - develop → 测试环境
  - release/* → 预发环境
  - main → 手动生产
      ↓
服务器
  - 拉取 Docker 镜像
  - PM2 重启容器
  - Nginx 提供服务

特点:

  • 自动化 → 减少人为出错
  • 多环境 → 测试/预发/生产隔离
  • 安全 → 敏感文件保护 + MR 审批
  • 可追踪 → GitHub Actions 日志 + PM2 管理
相关推荐
Amos_Web7 分钟前
通过 Rspack 源码学 Rust(二):所有权、借用与 `&mut`
前端
计算机魔术师14 分钟前
AI公司把「灾难性风险」写进招股书?Anthropic这5处反常
前端
西凉的悲伤14 分钟前
Jsoup 库 HTML 解析详解
java·前端·html·jsoup
niucloud-admin17 分钟前
NIUCLOUD PHP SAAS上门家政使用文档
前端·人工智能·ai编程
不一样的故事12629 分钟前
Prompt 工程(Prompt Engineering)
前端·人工智能·python
ZoeLandia33 分钟前
React08:自定义 Hook
开发语言·前端·react.js·typescript
2601_9499706934 分钟前
msgpackr 跨端三方库仓颉适配全流程
前端·javascript·flutter
Software攻城狮44 分钟前
【uniapp和普通web 端开发的区别】
前端·uni-app·notepad++
IT_陈寒1 小时前
Vue项目实战经验分享:动态组件在Keep-Alive下的缓存陷阱
前端·人工智能·后端
数智奔流1 小时前
MiniMax的低价攻势,撞上“背题”疑云
前端·javascript·算法