本文目录导读:

自动化部署(也叫持续部署,CI/CD)核心目标是:将你的代码从仓库(如GitHub)自动、可靠地发布到服务器(或应用商店)上,省去人工登录服务器手动上传、重启的麻烦。
下面我会从通用流程、主流工具和一个具体的手把手例子(基于GitHub Actions) 来为你说明。
自动化部署的核心流程
无论用什么工具,自动化部署都遵循以下几个步骤(流水线 Pipeline):
- 代码提交:开发者将代码
git push到远程仓库(GitHub, GitLab, Gitee等)。 - 触发构建:仓库检测到代码变更,自动通知CI/CD服务器。
- 构建与测试:
- 前端:
npm install->npm run build(生成 dist 文件夹)。 - 后端:
mvn package或docker build。 - 运行测试:单元测试、集成测试,失败则终止。
- 前端:
- 制品/镜像生成:
- 将构建产物打包(如 jar包,或 Docker 镜像)。
- 将产物上传到仓库(如 Docker Hub,阿里云镜像仓库,或简单的打包文件)。
- 部署到目标环境:
- 服务器:通过SSH将文件复制到服务器,重启服务。
- Kubernetes:更新K8s集群中的镜像版本。
- 云服务:调用云厂商API(如AWS CodeDeploy,阿里云 ECS部署)。
常见的自动化部署工具
- GitHub Actions:最流行,与GitHub深度集成,免费额度够用。适合个人/小团队。
- GitLab CI/CD:如果代码托管在GitLab,首选,功能强大。
- Jenkins:老牌、功能最全,可高度自定义。适合大型企业/复杂项目。
- Vercel / Netlify:零配置部署前端/静态网站,非常省心。
- 阿里云/腾讯云/CodePipeline:与云平台深度绑定,适合云上部署。
手把手实操:用 GitHub Actions 自动部署前端网站到 Nginx 服务器
场景:你有一个 Vue/React 项目,托管在 GitHub,你有一台 Linux 服务器(IP: 2.3.4),装好了 Nginx,你想每次 git push 到 main 分支,代码就自动编译并部署到服务器的 /var/www/html 目录。
第1步:在 GitHub 仓库中设置“密钥”
需要在 GitHub 中保存服务器的登录凭据,但又不能直接在代码里写密码。
- 打开你的 GitHub 仓库 ->
Settings->Secrets and variables->Actions。 - 点击
New repository secret。 - 添加以下两个密钥(名称自己定义,但要记住):
SERVER_HOST:服务器 IP 地址(如2.3.4)。SERVER_USER:登录用户名(如root)。SERVER_SSH_KEY:你的服务器SSH私钥(先在你的电脑通过ssh-keygen生成公钥,把公钥放到服务器~/.ssh/authorized_keys,然后把私钥内容复制粘贴到这里)。
第2步:在项目根目录创建 GitHub Actions 配置文件
在你的项目根目录,创建文件夹 .github/workflows/。
在里面创建一个文件,deploy.yml。
如下(已加详细注释):
# 工作流名称
name: Deploy to Nginx Server
# 触发条件:当 main 分支有 push 时触发
on:
push:
branches:
- main
# 定义工作流中的“任务(jobs)”
jobs:
build-and-deploy:
# 运行环境:最新版 Ubuntu
runs-on: ubuntu-latest
# 步骤执行
steps:
# 步骤1:拉取代码
- name: Checkout code
uses: actions/checkout@v4
# 步骤2:设置 Node.js 环境(根据你的项目版本调整)
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
# 步骤3:安装依赖并构建(前端项目打包)
- name: Install dependencies and build
run: |
npm install
npm run build # 假设构建后生成 dist 文件夹
# 步骤4:通过 SSH 将构建产物部署到服务器
- name: Deploy to server via SSH
uses: easingthemes/ssh-deploy@v5
with:
# 从 Secrets 中读取服务器信息(安全)
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
REMOTE_HOST: ${{ secrets.SERVER_HOST }}
REMOTE_USER: ${{ secrets.SERVER_USER }}
# 本地要上传的文件夹(构建产物目录)
SOURCE: 'dist/'
# 服务器上的目标路径(Nginx 的根目录)
TARGET: '/var/www/html/'
# 上传前清空目标目录,防止旧文件残留
ARGS: '-rltgoDzvO --delete'
# 可选步骤5:重启 Nginx 或发送通知
- name: Restart Nginx
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
sudo systemctl reload nginx
echo "部署成功!"
第3步:提交并观察效果
- 将上述文件
deploy.yml提交并推送到 GitHub 的main分支。git add . git commit -m "Add CI/CD pipeline" git push origin main
- 打开 GitHub 仓库,点击顶部 Actions 选项卡,你会看到一个新任务正在运行。
- 点击进入,可以看到每一个步骤的执行日志。
- 成功:日志显示绿色,访问你的服务器 IP,看到的是最新的代码。
- 失败:日志显示红色,查看是哪一步出错(比如SSH连接失败、依赖安装失败等)。
针对不同场景的常见变体
-
后端项目(Java/Spring Boot):
- 步骤4:用
mvn package代替npm run build。 - 步骤5:上传目标不再是静态文件,而是
target/*.jar。 - 步骤6:执行 SSH 命令,杀掉旧进程,启动新
java -jar。
- 步骤4:用
-
Docker 容器化部署:
- 步骤4:构建 Docker 镜像:
docker build -t myapp:latest . - 步骤5:推送到镜像仓库:
docker push myrepo/myapp:latest - 步骤6:SSH 到服务器,拉取新镜像并重新运行容器:
docker pull ... && docker run ...
- 步骤4:构建 Docker 镜像:
-
静态网站(最佳实践:使用 Vercel / Netlify):
- 无需自己写 YAML,只需将 GitHub 仓库连接到 Vercel,它自动检测、构建、部署,甚至给你一个免费域名(
xxx.vercel.app),这是最简单部署前端的方式。
- 无需自己写 YAML,只需将 GitHub 仓库连接到 Vercel,它自动检测、构建、部署,甚至给你一个免费域名(
避坑指南(常见失败原因)
- SSH 密钥权限不对:私钥文件在 GitHub Secrets 里没问题,但服务器上的公钥(
authorized_keys)权限必须是600(仅自己可读写),文件夹~/.ssh权限必须是700。 - Nginx 目录权限:GitHub 上传时使用的用户(如 root)需要有
/var/www/html的写入权限。 - Node 版本冲突:GitHub 服务器默认 Node 版本可能和你的项目不兼容,务必在 YAML 里明确指定
node-version。 - 忽略了
.gitignore:确保构建产物(如dist,target)没有被.gitignore忽略,否则无法找到上传的文件,或者,你可以在本地构建,但一般不推荐。 - 路径错误:区分好
SOURCE(本地,相对于仓库根目录)和TARGET(远程服务器绝对路径)。
自动化部署其实是个“配方”:
- 触发:代码推送。
- 构建:在你的CI/CD机器(如GitHub Actions)上编译打包。
- 传输:通过SSH或Docker Registry把产物送到服务器。
- 重启:让新代码生效。
最好的学习方式:去你的一个闲置项目里,根据上面的 deploy.yml 模板,改一下 SOURCE 和 TARGET 路径,实际触发一次,成功那一刻的感觉非常好。