(开篇:一张对比图,左边是手动FTP的混乱界面,右边是自动化部署的简洁流水线,配文:”从手动到自动,效率提升不是一点点”)
先看核心思路:自动化部署到底在做什么?
ba(0,0,0,.08);”
loading=”lazy” width=”800″ height=”500″>
自动化部署的本质就是把“构建 + 上传 + 重启”这三步手工操作变成脚本或工具的自动执行。原来你可能要做:本地跑npm run build -> 打开FTP -> 上传dist文件夹 -> SSH登录服务器 -> 移动文件 -> 重启Nginx。现在只需:git push或者按一个按钮,后面全部自动搞定。
我选择的方案是GitHub Actions + Nginx + 一个简单的部署脚本,因为它零成本、易上手,而且现在几乎所有项目都托管在GitHub上。
第一步:项目结构和服务端准备
自动化部署的第一步,是让你的代码和服务器能“对话”。先看我的项目目录结构:
“`
my-project/
├── .github/
│ └── workflows/
│ └── deploy.yml # GitHub Actions 配置文件
├── src/ # 源代码
├── dist/ # 构建产物(.gitignore中忽略)
├── deploy.sh # 本地测试用的部署脚本(可选)
└── package.json
这是为什么要这么写:.github/workflows/是GitHub Actions的默认读取路径,你放一个YAML文件,GitHub就会在每次代码推送时自动执行。
然后,服务器上也需要准备环境。假设你的服务器是Ubuntu,确保安装了Nod
e.js和Nginx。登录服务器,执行:
`bash
安装Nginx
sudo apt update && sudo apt install nginx -y
安装Node.js(如果用LTS版本)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
创建一个部署目录
sudo mkdir -p /var/www/my-project
sudo chown -R $USER:$USER /var/www/my-project
`
这个部署目录就是最后放静态文件的地方。Nginx的配置可以简单点:
`nginx
server {
listen 80;
server_name your-domain.com;
root /var/www/my-project;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
`
注意,这里try_files那一行是为了支持Vue或React的路由模式,否则刷新页面会404。
第二步:配置GitHub Actions工作流
重点来了。在.github/workflows/deploy.yml里写这个:
`yaml
name: Deploy to Production
on:
push:
branches:
- main # 只有main分支推送才触发
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: 1. 检出代码
uses: actions/checkout@v3
- name: 2. 设置Node环境
uses: actions/setup-node@v3
with:
node-version: 18
- name: 3. 安装依赖并构建
run: |
npm ci # 比npm install更可靠,锁定版本
npm run build
- name: 4. 上传构件到服务器
uses: easingthemes/ssh-deploy@v4
with:
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
REMOTE_HOST: ${{ secrets.SERVER_HOST }}
REMOTE_USER: ${{ secrets.SERVER_USER }}
SOURCE: dist/
TARGET: /var/www/my-project/
`
为什么要这么写?这里每个步骤都有讲究:
- 使用npm ci
而不是npm install:因为ci会严格遵循package-lock.json,避免本地和线上依赖版本不一致导致的“可以跑啊,怎么部署就报错”的玄学问题。 - easingthemes/ssh-deploy
这个Action:它会把dist/文件夹通过SSH上传到服务器的目标路径。这里最关键的是secrets——这些是敏感信息,千万不要直接写在YAML文件里。
怎么设置secrets?去你的GitHub仓库页面 -> Settings -> Secrets and variables -> Actions -> New repository secret。添加这三个:
- SERVER_SSH_KEY
:服务器SSH私钥(不是公钥!) - SERVER_HOST
:服务器IP或域名 - SERVER_USER
:登录用户名(比如ubuntu或root)
关于SSH密钥:要在服务器上生成一对密钥,然后把公钥添加到~/.ssh/authorized_keys,私钥粘贴到GitHub Secrets。这个设计真的反人类吗?其实不是,它保证了只有有私钥的人才能部署,安全性更高。我第一次配的时候折腾了两小时,就是因为把公钥和私钥搞反了。
(核心:一张流程图,展示从git push到代码部署到服务器的完整流水线,标注每个步骤耗时)
另一个坑:构建速度优化
第一次跑通后,我发现整个流程耗时4分20秒,其中npm ci和npm run build占了3分钟。对于小项目来说还行,但项目一大,这速度就接受不了了。
优化方案是缓存node_modules:
`yaml
- name: 缓存node_modules
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
`
把这个步骤放在“安装依赖”之前。这样,只要package-lock.json没变,就直接用缓存,从3分钟降到10秒。整体流程从4分20秒降到1分半,爽到飞起。
还有个技巧:预部署测试
你肯定不想每次推送都直接上线吧?万一代码有问题呢?所以我在工作流里加了一个“运行测试”的步骤:
`yaml
- name: 运行单元测试
run: npm test
continue-on-error: false # 测试失败就终止流程
`
如果测试失败,整个部署就中止,代码不会推送到服务器。这个功能救过我一次:有一次我改了路由配置,忘记更新某个组件,本地跑的时候没问题(因为懒,没跑测试),结果测试在CI环境里报错了,部署戛然而止,我赶紧修复了才重新推送。
进阶:多环境部署
当项目发展到有dev、staging、production三个环境时,手动改YAML配置简直噩梦。我用的是环境变量的方式:
`yaml
- name: 构建指定环境
run: |
if [ "${{ github.ref }}" == "refs/heads/dev" ]; then
npm run build:dev
elif [ "${{ github.ref }}" == "refs/heads/staging" ]; then
npm run build:staging
elif [ "${{ github.ref }}" == "refs/heads/main" ]; then
npm run build:prod
fi
`
然后在package.json里定义不同的构建命令:
`json`
{
"scripts": {
"build:dev": "vue-cli-service build --mode dev",
"build:staging": "vue-cli-service build --mode staging",
"build:prod": "vue-cli-service build --mode production"
}
}
这样,你只要在dev分支推送,就会自动部署到开发服务器;在main分支推送,才会部署到生产。这个设计真的反人类吗?其实很合理,它严格隔离了环境,避免了“误推送上线”的惨剧。
最后说点落地体会
这套流程我已经用了半年多,配合团队一起用,效果显著:
- 部署时间从手动操作的5分钟,降到了自动化后的1分半(含测试)
- 人为错误从每月至少1次到几乎为零
- 前端同学终于可以安心下班,不用守着电脑等部署
当然,也有遗憾:如果你用的是私有Git仓库,GitHub Actions有额度限制,免费版一个月2000分钟分钟,对小团队足够。我们团队3个人,一个月大概用掉300-400分钟。
(总结前:一张团队协作的截图,显示GitHub Actions跑成功的通知,配文:“代码推送即上线,老板再也不用催了”)
总结一下,你可以立刻用的三个点
,用actions/checkout + ssh-deploy组合,半小时内就能跑通“push即上线”的最基础流程。记住,自动化部署不是炫技,是让你把时间花在写业务代码上。相信我,花一个下午搞定它,接下来半年都开心。