本文是部署系列的延续。SSH 密钥配置和 GitHub Secrets 设置与后端篇相同(参考前一篇文章),本文不再重复,重点讲 Vue 前端的自动部署流程。
一、流程回顾
本地 push → GitHub 私有仓库 → GitHub Actions → SSH 连接 ECS → git pull → npm build → 更新 Nginx
前提条件(参考上一篇):
- ECS 上已配置 SSH 密钥
- GitHub 仓库已添加
ECS_HOST、ECS_USER、ECS_SSH_KEY三个 Secrets - ECS 上已 clone 前端代码到
/opt/app/myapp-frontend
二、前端 Workflow
创建 .github/workflows/deploy-frontend.yml:
name: Deploy Frontend to ECS
on:
push:
branches:
- main
paths:
- 'frontend/**' # 只在前端代码变更时触发
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.ECS_HOST }}
username: ${{ secrets.ECS_USER }}
key: ${{ secrets.ECS_SSH_KEY }}
script: |
cd /opt/app/myapp-frontend
git pull origin main
npm install
npm run build
rm -rf /opt/app/frontend/dist
cp -r dist/ /opt/app/frontend/dist
nginx -t && systemctl reload nginx
echo "前端部署完成"
脚本逐行说明:
| 命令 | 作用 |
|---|---|
git pull origin main | 拉取最新前端代码 |
npm install | 安装/更新依赖 |
npm run build | 构建生产版本到 dist/ |
rm -rf /opt/app/frontend/dist | 删除旧版本 |
cp -r dist/ /opt/app/frontend/dist | 复制新版本 |
nginx -t && systemctl reload nginx | 检查配置后平滑重载 |
注意:nginx reload 不会中断现有连接,比 restart 更平滑。
三、前后端合并 Workflow
如果不想维护两个 workflow 文件,可以合并为一个,用 paths-filter 自动判断:
name: Deploy to ECS
on:
push:
branches:
- main
jobs:
changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
backend: 'backend/**'
frontend: 'frontend/**'
deploy-backend:
needs: changes
if: ${{ needs.changes.outputs.backend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.ECS_HOST }}
username: ${{ secrets.ECS_USER }}
key: ${{ secrets.ECS_SSH_KEY }}
script: |
cd /opt/app/myapp-backend && git pull origin main
mvn clean package -DskipTests
mv target/*.jar /opt/app/myapp.jar
systemctl restart myapp
deploy-frontend:
needs: changes
if: ${{ needs.changes.outputs.frontend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.ECS_HOST }}
username: ${{ secrets.ECS_USER }}
key: ${{ secrets.ECS_SSH_KEY }}
script: |
cd /opt/app/myapp-frontend && git pull origin main
npm install && npm run build
rm -rf /opt/app/frontend/dist
cp -r dist/ /opt/app/frontend/dist
nginx -t && systemctl reload nginx
优势:只改后端代码时自动跳过前端部署,反之亦然。一个文件管理全部,不用来回切换。
四、前端特殊处理
Nginx 缓存问题
部署新版本后用户可能看到旧页面,因为 Nginx 默认会缓存静态资源。在 Nginx 配置中明确缓存策略:
# index.html 不缓存(确保新版本立即生效)
location = /index.html {
root /opt/app/frontend/dist;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# JS/CSS 文件名带 hash(Vue 默认),可以长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf)$ {
root /opt/app/frontend/dist;
expires 30d;
add_header Cache-Control "public, immutable";
}
构建内存不足
Vue 项目大型时可能 OOM,在 workflow 脚本中改为:
NODE_OPTIONS="--max-old-space-size=4096" npm run build
五、回滚
手动回滚前端:
cd /opt/app/myapp-frontend
git log --oneline -5
git reset --hard <commit>
npm install && npm run build
rm -rf /opt/app/frontend/dist
cp -r dist/ /opt/app/frontend/dist
nginx -t && systemctl reload nginx
六、部署效果
配置完成后,只要 push 前端代码到 main 分支:
- GitHub Actions 自动触发
- SSH 到 ECS 拉取最新代码
- 自动构建并更新 Nginx
- 30 秒到 2 分钟完成(取决于项目大小)
不再需要手动 npm run build → scp 上传,真正做到提交即部署。
总结
前端自动部署的核心脚本只有几行:
git pull → npm install → npm run build → 替换 dist → nginx reload
和后端篇配合,整个项目的部署完全自动化。前后端的 CI/CD 模式相同,差别只在构建命令。