手工部署的流程通常是:本地 npm run build → 压缩 dist → 打开 FTP 工具 → 上传到服务器 → 刷新页面看有没有白屏。这个过程重复、低效、容易出错,一旦涉及多环境(测试、预发、生产)就更加繁琐。自动化部署的目标是:代码推送到指定分支后,构建、测试、部署一气呵成,无需人工干预。
自动化部署的典型环节
一个完整的自动化部署流水线通常包含以下步骤:
代码推送 → 触发构建 → 安装依赖 → 代码检查/测试 → 项目构建 → 部署到目标环境 → 通知
其中“部署到目标环境”这一步根据项目架构有多种实现方式,下面以最常见的三种场景展开。
场景一:部署到自建服务器(Nginx)
适用于公司的虚拟机、云服务器,通过 Nginx 托管静态资源。
前置准备:
- 服务器已安装 Nginx,并配置好站点根目录(如
/var/www/my-app)。 - 服务器允许 SSH 密钥登录,并且已配置好免密登录(推荐使用部署专用密钥)。
GitHub Actions 工作流示例:
# .github/workflows/deploy.yml
name: Deploy to Server
on:
push:
branches: [main] # 推送到 main 分支时触发
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test --if-present
- name: Build project
run: npm run build
env:
VITE_API_BASE: ${{ secrets.VITE_API_BASE }} # 注入环境变量
- name: Deploy to server
uses: easingthemes/ssh-deploy@v4
with:
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
ARGS: "-avz --delete" # 同步并删除多余文件
SOURCE: "dist/"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: ${{ secrets.REMOTE_PATH }} # 如 /var/www/my-app
关键点说明:
npm ci比npm install更快且严格依据 lock 文件,适合 CI 环境。--if-present表示如果项目没有定义 test 脚本,不会报错。ARGS: "-avz --delete"保证服务器上的dist内容与本次构建完全一致,自动清除旧文件。- 所有敏感信息(服务器 IP、密钥、路径、环境变量)都存储在 GitHub 仓库的 Settings → Secrets and variables → Actions 中,不会暴露在代码里。
Vite 项目的额外注意:
- 如果项目部署在子路径下(如
https://example.com/admin/),需要在vite.config.js中设置base: '/admin/',否则资源路径会 404。 - 如果使用了 Vue Router 的 history 模式,必须在 Nginx 配置中添加
try_files规则,避免刷新页面 404:
location / {
try_files $uri $uri/ /index.html;
}
场景二:部署到对象存储 + CDN(如阿里云 OSS、腾讯云 COS、AWS S3)
适用于纯静态站点、前端资源完全托管在云服务上的场景,优势在于免运维、高可用、成本低。
基本流程: 构建完成后,使用云厂商提供的 CLI 工具将 dist 目录内容上传到对应的 Bucket,并可选刷新 CDN 缓存。
以腾讯云 COS 为例的 GitHub Actions 步骤片段:
- name: Upload to COS
uses: zkqiang/tencent-cos-action@v0.1.0
with:
secret_id: ${{ secrets.TENCENT_SECRET_ID }}
secret_key: ${{ secrets.TENCENT_SECRET_KEY }}
bucket: my-bucket-1250000000
region: ap-guangzhou
local_path: dist
remote_path: /
clean: true # 上传前删除 bucket 中同名文件
上传完成后,如果使用了 CDN,可以通过脚本调用刷新接口,确保用户能立刻看到最新内容。这一步通常封装在单独的 Action 中或使用 run 执行 curl 命令。
场景三:容器化部署(Docker + Nginx)
适用于微服务架构或需要统一运行环境的团队。
项目根目录编写 Dockerfile:
FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
自动化流程中,先构建镜像,推送到镜像仓库(Docker Hub 或私有仓库),然后让服务器拉取新镜像并重启容器。如果需要多台服务器滚动更新,通常会接入 Kubernetes 等编排工具,这超出了前端日常范畴,但基础思路相同。
多环境部署
在第 17.3 节中已经配置了开发、测试、生产环境。自动化部署时只需根据触发分支加载不同的 Secrets 变量即可。例如:
- name: Build for Staging
if: github.ref == 'refs/heads/develop'
run: npm run build -- --mode staging
- name: Build for Production
if: github.ref == 'refs/heads/main'
run: npm run build -- --mode production
对应 .env.staging 和 .env.production 文件中的 VITE_API_BASE 等变量会自动生效。
部署后的验证与回滚
自动化部署的最后一步通常加入健康检查或冒烟测试。可以写一个简单的脚本,用 curl 请求首页和关键 API,确认返回状态码 200 且包含预期内容:
- name: Health check
run: |
sleep 10
curl -f https://your-domain.com || exit 1
如果发现问题,快速回滚策略有:
- 服务器部署:保留上一个版本的
dist备份,通过 Nginx 切换软链接。 - 对象存储:大多数云服务提供版本管理和回滚功能。
- Docker 部署:直接切换容器镜像标签到上一个版本。
这些措施可以在配置流水线时一并考虑,让“部署”这件事从压力源变成一次普通的代码推送。