曾几何时,我们更新网站的流程是:本地打包 -> 打开 FTP 软件 -> 拖拽上传 -> 重启服务器。这不仅效率极低,而且一旦出错极难回滚。

自从全面切入 CI/CD(持续集成/持续部署)工作流后,我彻底解放了双手。今天来聊聊目前最推荐的轻量级方案:GitHub Actions。

什么是 GitHub Actions?

简单来说,它就是 GitHub 提供的一台免费服务器,当你每次提交代码 (Push) 时,它会自动按照你写好的脚本执行一系列动作:测试、编译、甚至通过 SSH 登录到你的服务器完成部署。

对于个人开发者和中小团队来说,GitHub Actions 最大的优势是零成本——公开仓库免费使用每月 2000 分钟的构建时长,足以覆盖绝大多数项目的自动化需求。

基础实战:部署一个静态博客

假设我们要自动部署一个前端项目,只需要在项目根目录新建 .github/workflows/deploy.yml 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
name: Deploy Website
on:
push:
branches:
- 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: '20'
cache: 'npm'

- name: Install and Build
run: |
npm ci
npm run build

- name: Deploy via SCP
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "dist/"
target: "/var/www/my-website"

密钥管理

注意上面的 ${{ secrets.SERVER_IP }}。永远不要把服务器 IP 和私钥直接写在代码里!在 GitHub 项目的 Settings → Secrets and variables → Actions 中配置这些环境变量,既安全又优雅。

推荐的密钥配置清单:

密钥名称 用途
SERVER_IP 服务器 IP 地址
SERVER_USER SSH 用户名
SSH_PRIVATE_KEY SSH 私钥(注意换行符格式)
ENV_FILE 生产环境变量文件内容

私钥的坑

如果你直接把私钥粘贴到 GitHub Secrets,会因为换行符被吞掉导致 SSH 连接失败。正确的做法是先用 base64 编码:

1
cat ~/.ssh/id_rsa | base64 -w 0

然后在 Action 中解码使用:

1
2
3
4
- name: Setup SSH Key
run: |
echo "${{ secrets.SSH_PRIVATE_KEY_BASE64 }}" | base64 -d > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa

进阶:多环境部署

真实项目中往往有开发 (dev)、预发布 (staging) 和生产 (production) 三个环境。可以通过分支来区分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
on:
push:
branches:
- dev # 开发环境
- staging # 预发布环境
- main # 生产环境

jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.ref_name }}
steps:
# ... 构建步骤
- name: Deploy
run: |
if [ "${{ github.ref_name }}" = "main" ]; then
echo "Deploying to PRODUCTION"
# 生产环境部署命令
elif [ "${{ github.ref_name }}" = "staging" ]; then
echo "Deploying to STAGING"
# 预发布环境部署命令
fi

出错了怎么办?回滚策略

CI/CD 自动化的最大风险不是构建失败,而是把坏代码自动推上线。建议加入审批门禁。

对于个人项目,最简单的回滚手段是保留上一次构建产物:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- name: Backup previous deploy
run: |
if [ -d "/var/www/my-website" ]; then
cp -r /var/www/my-website /var/www/my-website.backup
fi

- name: Rollback on failure
if: failure()
run: |
if [ -d "/var/www/my-website.backup" ]; then
rm -rf /var/www/my-website
mv /var/www/my-website.backup /var/www/my-website
echo "Rollback completed"
fi

缓存加速构建

如果你的项目依赖较多(如 node_modules),每次从头安装非常浪费时间。GitHub Actions 内置了缓存机制:

1
2
3
4
5
6
7
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-

总结

只要配置好这一次,以后所有的更新只需要敲一句 git push,剩下的事情去喝杯咖啡,机器会自动帮你完成。从一个手动传 FTP 的新手,到掌握自动化部署的熟手,其实只需要一个下午的时间。

这是现代软件开发最值得投资的技能之一——你的时间应该花在写代码上,而不是花在部署代码上。