GitHub 自托管 Runner 自动部署实战指南
一、概述
1. 简介
A. 是什么
GitHub 自托管 Runner(Self-hosted Runner)是 GitHub Actions 的一种运行器类型,用于在你自己提供的服务器上执行 CI/CD 工作流。与 GitHub 托管的 Runner 不同,自托管 Runner 运行在你自己的基础设施上,可以访问私有网络、数据库、Docker 环境等资源。
B. 为什么学
- 告别手动 rsync 部署的繁琐操作
- 实现代码推送后自动部署的完整流程
- 提升团队协作效率和部署可靠性
- 不占用 GitHub 托管 Runner 的免费额度
C. 学完能做什么
- 在云服务器上配置 GitHub 自托管 Runner
- 编写 GitHub Actions workflow 实现自动部署
- 配置服务器权限确保部署安全
- 优化构建缓存提升部署速度
2. 前置知识
A. 必备技能
- 基本 Linux 命令操作
- Git 基本使用(推送代码到 GitHub)
- 了解 SSH 和服务器基本概念
B. 推荐知识
- GitHub Actions 基础概念
- Nginx 等 Web 服务器配置
- systemd 服务管理
二、问题背景
1. 传统部署痛点
手动部署的常见流程如下:
npm run build
rsync -avz build/ user@server:/var/www/html/
ssh user@server "sudo systemctl reload nginx"这种方式存在以下问题:
- 操作繁琐,每次更新都需要重复相同步骤
- 容易遗漏步骤导致部署失败
- 本地环境与服务器环境不一致可能引发问题
- 部署历史难以追溯
- 深夜紧急修复时容易被人为错误影响
2. 自动部署的价值
通过自托管 Runner 实现 CI/CD 自动化后:
- 代码推送即触发自动部署
- 所有操作在 GitHub UI 可追溯
- 服务器主动拉取并执行部署,无需开放 SSH 端口
- 一次配置,永久省心
三、核心概念
1. Self-hosted Runner 工作原理
自托管 Runner 是运行在你自己的服务器上的代理程序,它通过 HTTPS 出站连接到 GitHub,接收并执行工作流任务。
graph LR
A[开发者] -->|推送代码| B[GitHub 仓库]
B -->|触发 workflow| C{GitHub Actions}
C -->|分配任务| D[Self-hosted Runner]
D -->|执行构建| E[本地环境]
E -->|同步文件| F[Web 目录]
D -->|重载服务| G[Nginx]2. 与 GitHub 托管 Runner 的区别
| 特性 | GitHub 托管 Runner | 自托管 Runner |
|---|---|---|
| 运行位置 | GitHub 提供的虚拟机 | 你自己的服务器 |
| 网络访问 | 公网 | 可访问私有资源 |
| 成本 | 占用免费额度 | 无额外费用 |
| 环境定制 | 有限 | 完全可控 |
| 适用场景 | 通用 CI/CD | 部署到自有服务器 |
3. 安全优势
相比传统 SSH + rsync 方式,自托管 Runner 具有更好的安全性:
- 无需开放 SSH 22 端口到公网
- Runner 使用专用账号运行,权限可精确控制
- 所有操作记录在 GitHub Actions 日志中
- 支持使用 GitHub 的身份认证和审计功能
四、环境准备
1. 系统要求
- 操作系统:Ubuntu 20.04+ / CentOS 7+ / Debian 10+
- 权限:非 root 用户,但需要 sudo 权限
- 网络:服务器需能访问 GitHub(出站 443 端口)
2. 前置条件
- GitHub 仓库(公开或私有均可)
- 云服务器一台
- 基本的 Web 服务器环境(如 Nginx)
五、配置步骤
1. 在 GitHub 创建 Runner
进入 GitHub 仓库页面,依次点击:
- Settings(设置)
- Actions(左侧菜单)
- Runners
- New self-hosted runner
选择操作系统和架构:
- OS:Linux
- Architecture:x64
- 复制生成的配置命令(包含临时 token)
2. 在服务器安装 Runner
使用非 root 用户执行以下命令:
# 1. 创建专用目录
mkdir -p ~/actions-runner && cd ~/actions-runner
# 2. 下载 Runner(替换为 GitHub 提供的版本链接)
curl -o actions-runner-linux-x64-2.320.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.320.0/actions-runner-linux-x64-2.320.0.tar.gz
# 3. 解压
tar xzf ./actions-runner-linux-x64-2.320.0.tar.gz
# 4. 配置 Runner(使用 GitHub 生成的命令)
./config.sh --url https://github.com/yourname/repo --token YOUR_TOKEN配置时的交互提示:
- Runner name:建议使用描述性名称,如
prod-server-1 - Additional labels:可添加标签如
production、web等 - Work folder:保持默认
_work即可
3. 配置系统服务
将 Runner 配置为 systemd 服务,实现开机自启:
# 安装服务
sudo ./svc.sh install $(whoami)
# 启动服务
sudo ./svc.sh start
# 验证状态
systemctl status actions.runner.*看到 Active: active (running) 表示服务已成功运行。
回到 GitHub 的 Runners 页面,应该能看到新添加的自托管 Runner 显示为在线状态。
4. 配置服务器权限
为了确保 Runner 能够执行部署操作,需要配置相应的权限:
# 1. 创建部署目录
sudo mkdir -p /var/www/html
# 2. 设置目录权限(假设 Runner 用户为 ubuntu)
sudo chown -R ubuntu:www-data /var/www/html
sudo chmod -R g+rwxs /var/www/html
# 3. 配置 sudo 免密(仅限特定命令)
echo "ubuntu ALL=(root) NOPASSWD: /usr/bin/systemctl reload nginx" | \
sudo tee /etc/sudoers.d/deploy安全注意事项:
- 绝对不要使用 root 用户运行 Runner
- sudo 免密仅限于必要的命令(如 systemctl reload)
- 定期检查 Runner 用户的权限范围
5. 创建 Workflow 文件
在 GitHub 仓库中创建 .github/workflows/deploy.yml 文件:
name: Deploy to Production Server
on:
push:
branches: [ main ]
paths:
- 'website/**' # 仅当特定目录变化时触发
jobs:
deploy:
runs-on: self-hosted # 指定使用自托管 Runner
env:
DEPLOY_PATH: /var/www/html
# npm 国内镜像加速
NODEJS_ORG_MIRROR: https://npmmirror.com/mirrors/node/
NPM_CONFIG_REGISTRY: https://registry.npmmirror.com
steps:
# 1. 检出代码
- name: Checkout repository
uses: actions/checkout@v4
# 2. 设置 Node.js 环境
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
# 3. 安装依赖并构建
- name: Build project
run: |
cd website
npm ci --prefer-offline
npm run build
# 4. 同步文件到部署目录
- name: Deploy to server
run: |
sudo mkdir -p ${{ env.DEPLOY_PATH }}
sudo chown -R $USER:www-data ${{ env.DEPLOY_PATH }}
rsync -av --delete \
website/build/ \
${{ env.DEPLOY_PATH }}/
# 5. 重载 Web 服务器
- name: Reload Nginx
run: sudo systemctl reload nginx || trueWorkflow 工作流程:
sequenceDiagram
participant Dev as 开发者
participant GH as GitHub
participant Runner as 自托管 Runner
participant Server as 云服务器
Dev->>GH: 推送代码到 main 分支
GH->>Runner: 触发 workflow
Runner->>Runner: 检出代码
Runner->>Runner: 安装依赖
Runner->>Runner: 构建项目
Runner->>Server: 同步文件
Runner->>Server: 重载 Nginx
Server-->>Dev: 部署完成六、高级配置
1. 构建缓存优化
GitHub Actions 支持缓存依赖,大幅提升构建速度:
- Node.js 二进制文件缓存在
~/.cache/actions-node node_modules通过cache: 'npm'自动缓存
首次运行后,后续构建速度可提升 3-5 倍。
2. 多环境部署
通过使用不同的 label,可以将工作流分配到不同的 Runner:
jobs:
deploy-production:
runs-on: [self-hosted, production]
# ...
deploy-staging:
runs-on: [self-hosted, staging]
# ...3. 部署前验证
可以在部署前增加测试步骤:
- name: Run tests
run: |
cd website
npm test
- name: Deploy to server
if: success() # 仅在测试通过后部署
run: |
# 部署命令七、常见问题
1. Runner 离线
检查服务状态:
systemctl status actions.runner.*
sudo ./svc.sh start确保服务器能访问 GitHub:
curl -I https://github.com2. 权限错误
- 确认 Runner 用户对部署目录有写权限
- 检查 sudoers 配置是否正确
- 避免 Runner 使用 root 用户运行
3. 构建失败
- 检查 workflow 语法是否正确
- 查看 Actions 日志定位具体错误
- 确认服务器环境满足构建要求
4. npm 安装缓慢
在 workflow 中配置国内镜像源:
env:
NPM_CONFIG_REGISTRY: https://registry.npmmirror.com八、最佳实践
1. 安全实践
- 使用最小权限原则配置 Runner 用户
- 定期更新 Runner 版本
- 在 GitHub 设置中配置环境保护规则
- 敏感信息使用 GitHub Secrets 存储
2. 监控与日志
- 定期检查 Runner 运行状态
- 关注 workflow 执行时间和成功率
- 保留必要的构建日志用于问题排查
3. 维护建议
- 定期清理旧的构建产物
- 监控服务器磁盘使用情况
- 配置 Runner 的自动更新策略