如何使用 GitHub 将代码部署到你的服务器

当你把代码从 GitHub 自动部署到自己的服务器时,可以节省时间并避免出错。部署自动化能够带来更快的反馈,也有助于团队更高效地协作。借助 GitHub Actions、Webhook 和部署脚本等工具,你可以减少人为失误,让整个流程更加稳定可靠。即使你只掌握了 GitHub 和服务器管理的基础知识,也能搭建这套工作流,并很快看到改进效果。
关键要点
- 将代码部署自动化可以节省时间并减少错误。使用 GitHub Actions 和 Webhook 等工具,可以让流程更加顺畅。
- 准备好必要的工具和账户,包括 GitHub 仓库、云服务器以及部署脚本。这些基础配置是成功实现自动化的关键。
- 通过 SSH 密钥实现免密访问,保障服务器安全。这能确保只有受信任的系统可以连接到你的服务器。
- 在正式上线前,先在预发布服务器上测试部署流程。这样可以及早发现问题,保护生产环境。
- 使用 GitHub Secrets 安全存储敏感信息。这可以让密码和密钥不会暴露在工作流文件中。
自动部署的前置条件
所需工具与账户
在开始设置自动部署之前,你需要准备一些必要的工具和账户。它们将帮助你把 GitHub 上的代码连接到服务器,并让整个流程更加顺畅。
- 在线远程仓库:你需要一个 GitHub 账户,并拥有一个存放项目代码的仓库。
- 本地 Git 仓库:在你的电脑上配置一个本地 Git 仓库,用于管理代码变更。
- 云服务器:选择一个云服务器提供商,例如 Amazon EC2 或 Rackspace。你的网站或应用将运行在这里。
- 部署脚本:编写一个部署脚本,例如
deploy.php,用于拉取 GitHub 上的最新代码。 - 服务器上安装 Git:确保你的服务器已安装 Git,并且版本为最新。
- SSH 密钥设置:在服务器上生成 SSH 密钥,以实现与 GitHub 的安全免密通信。
- 将 SSH 公钥添加到 GitHub:把服务器的 SSH 公钥添加到你的 GitHub 账户中,以便服务器能够访问仓库。
- 设置 Post-Receive Hook:在 GitHub 中配置 post-receive hook,用于触发你的部署脚本。
提示:请妥善保管你的 SSH 密钥。绝不要将私钥分享给任何人。
准备你的服务器
你必须先准备好服务器,以便接收来自 GitHub 的代码更新。这样的设置可以确保每次自动部署都能顺利执行。
- 将你的 GitHub 仓库克隆到服务器上的某个目录。你可以为生产环境和预发布环境分别创建不同的目录。
- 编写 Bash 部署脚本,并赋予这些脚本执行权限,以便它们能够获取最新代码并运行。
- 订阅 GitHub 的 Webhook API。这样你的服务器就能监听事件,并在需要时自动开始部署流程。
下面是一个简单的仓库克隆命令:
git clone git@github.com:yourusername/your-repo.git
完成这些步骤后,你的服务器就可以进行自动部署了。每次部署新代码时,你都能节省时间并减少错误。
使用 GitHub Actions 自动部署代码
你可以借助 GitHub Actions 将代码自动部署到服务器。这个工具可以帮助你在每次推送变更时自动运行脚本并发布代码。你不再需要手动登录服务器或手动执行命令,整个过程会更加流畅且可重复。
创建工作流文件
要实现代码自动部署,你需要在仓库中创建一个工作流文件。这个文件会告诉 GitHub Actions:当你推送新代码时,需要执行哪些操作。请将该文件放在 .github/workflows/ 目录中,并命名为类似 main.yml 的名称。
下面是一个工作流文件示例:它会在每次推送标签时触发,并运行部署任务:
name: Deploy on Tag on: push: tags: - '*' jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v3 - name: Deploy to Test Server env: REMOTE_PATH: [your remote path location] if: startsWith(github.ref, 'refs/tags/') && contains(github.ref, 'rc') run: | mkdir -p ~/.ssh echo "${{ secrets.TEST_SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa cd ~/.ssh chmod 600 id_rsa ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ${{ secrets.TEST_SSH_USERNAME }}@${{ secrets.TEST_SERVER }} 'echo "${{secrets.REPO_DEPLOY_KEY}}" > ~/.ssh/gh_key && chmod 600 ~/.ssh/gh_key && eval `ssh-agent -s` && ssh-add ~/.ssh/gh_key && cd ${{ env.REMOTE_PATH }} && git fetch --tags && git checkout ${{ github.ref }} && /usr/bin/docker compose run --rm backend php yii migrate --interactive=0 && /usr/bin/docker compose run --rm backend php yii cache/flush-all && rm -f ~/.ssh/gh_key'
这个工作流会先检出你的代码,然后连接到服务器,并执行命令来更新项目。你可以根据自己的需要调整这些步骤。
在创建工作流文件时,你可能会遇到一些常见问题:
- 工作流没有触发。请确认文件位于
.github/workflows/main.yml。 - YAML 语法错误。请确保每一级缩进使用两个空格。
- 找不到命令。请检查 GitHub runner 上是否安装了所有所需工具。
你可以通过反复检查文件位置和语法来避免这些问题。
设置环境与 Secrets
在自动部署代码时,你必须保证服务器安全。绝不要把密码或私钥直接写进工作流文件。相反,你应该使用 GitHub Secrets 来存储敏感信息。
进入你的仓库设置页面,找到 “Secrets” 部分。添加 SSH 私钥、服务器用户名以及其他敏感信息。在工作流文件中,你可以使用 ${{ secrets.YOUR_SECRET_NAME }} 的形式来引用这些 Secrets。这样可以确保你的数据安全且不会暴露。
你还可以为测试环境和生产环境分别设置不同的 Environment。这样一来,你可以先把代码自动部署到测试服务器;如果一切正常,再部署到正式服务器。借助 GitHub Actions,你可以精确控制代码在何时、部署到哪里。
按照这些步骤操作后,每次你推送变更时,代码都会自动部署。你将节省时间、减少错误,并让整个部署流程更加稳固、安全。
使用 Webhook 实现自动部署
Webhook 是实现部署自动化的一种非常有力的方式。设置完成后,你的服务器可以监听来自 GitHub 的事件,并在收到通知后自动更新代码。如果你希望在自己的服务器上掌控整个部署流程,这种方法会非常适合。
编写 Webhook 监听脚本
首先,你需要一个用于监听 Webhook 请求的脚本。你可以使用 PHP、Node.js,或其他能够处理 HTTP POST 请求的语言。这个脚本会在你向仓库推送变更时接收来自 GitHub 的通知。
下面是一套典型的 Webhook 监听器配置流程:
- 将你的 Git 仓库分别克隆到生产环境和预发布环境对应的目录中。
- 为每个环境创建 Bash 脚本,并赋予这些脚本执行权限,以便自动运行。
- 编写处理 Webhook 事件的代码。很多开发者会在 Node.js 中使用
github-webhook-handler包,但你也可以使用 PHP 或 Python。 - 在 GitHub 仓库设置中配置 Webhook URL。选择用于触发 Webhook 的事件,例如 push 或 pull request。
- 测试并验证你的配置。你可以使用 PM2 这样的进程管理工具来监控脚本,并通过日志排查错误。
下面是一个简单的 PHP Webhook 监听脚本示例:
<?php
$secret = 'your_webhook_secret';
$payload = file_get_contents('php://input');
$signature = 'sha1=' . hash_hmac('sha1', $payload, $secret);
if (hash_equals($signature, $_SERVER['HTTP_X_HUB_SIGNATURE'])) {
// Run your deployment script
shell_exec('/path/to/deploy.sh');
http_response_code(200);
echo "Deployment triggered.";
} else {
http_response_code(403);
echo "Invalid signature.";
}
?>
提示:一定要使用 GitHub 提供的示例 payload 测试你的 Webhook 监听器。这样可以帮助你在影响线上站点之前发现错误。
配置 GitHub Webhook
创建好监听脚本之后,你还需要在 GitHub 仓库中配置 Webhook。这一步会把你的仓库和服务器连接起来,并告诉 GitHub 应该把通知发送到哪里。
按照以下步骤配置你的 Webhook:
- 编写处理 Webhook 事件的代码,并确保你的服务器拥有一个 GitHub 可以访问的公网 URL。
- 如果你想简化事件处理流程,可以使用像
github-webhook-handler这样的包。 - 运行你的服务程序,让它开始监听传入的 Webhook 请求。
- 进入 GitHub 仓库设置页面,新增一个 Webhook,并填写监听脚本的 URL。
- 选择应该触发 Webhook 的事件,例如 push 事件或 pull request。
在使用 Webhook 时,安全性非常重要。你需要确保只有 GitHub 才能触发服务器上的部署。以下是一些关键的安全注意事项:
| 安全注意事项 | 说明 |
|---|---|
| 使用密钥进行验证 | 为你的 Webhook 添加一个密钥,以帮助确认请求确实来自 GitHub。 |
| Webhook URL 的可访问性 | 请妥善保护你的 Webhook URL,不要随意公开,以防止未经授权的访问。 |
| 使用 HTTPS | 配置 HTTPS,以加密 GitHub 与服务器之间的通信。 |
注意:如果你使用了密钥,请同步更新监听脚本,以校验传入请求的签名。这会增加一层额外的安全保护。
完成这些步骤后,每次你向仓库推送代码,服务器都会自动部署最新版本。这样的配置可以节省时间,并减少手动操作带来的风险。
安全的服务器访问与 SSH 密钥
配置安全访问机制,是任何自动化部署流程中都非常关键的一部分。你需要确保只有受信任的用户和系统能够连接到服务器。使用 SSH 密钥可以帮助你实现安全、免密的连接。
生成 SSH 密钥
你可以通过生成 SSH 密钥,让部署流程安全地连接到服务器。请按以下步骤为部署用户配置 SSH 密钥:
- 在本地机器上生成一对新的 SSH 密钥:
ssh-keygen -t ed25519 -f ~/.ssh/blog_deployer - 在服务器上创建一个专门用于部署的用户:
useradd blog-deployer - 锁定该用户的密码,防止其通过密码登录:
passwd -l blog-deployer - 为新用户创建一个
.ssh目录:mkdir -p /home/blog-deployer/.ssh - 将公钥添加到
authorized_keys文件中:nano /home/blog-deployer/.ssh/authorized_keys - 修改主目录的所有权:
chown -R blog-deployer:blog-deployer /home/blog-deployer
这样配置之后,就只有你的部署系统才能连接到服务器并将项目部署到服务器上。
设置权限
你必须设置正确的权限,才能保证部署过程的安全。如果权限配置不当,攻击者可能会获得访问权限,甚至窃取数据。以下是一些最佳实践:
- 限制部署用户的 SSH 登录能力。你可以使用如下命令:
restrict,pty,no-agent-forwarding,no-port-forwarding,no-X11-forwarding,command="/usr/local/bin/rrsync -wo /var/www/blog" - 限制部署用户可执行的操作,只允许执行部署所需的最小权限操作。
- 将 Secrets 和密钥保存在安全的保管库中,并确保其在静态存储和传输过程中都经过加密。
- 定期审计并监控服务器访问情况。
- 定期轮换 SSH 密钥和各类敏感凭据。
提示:务必检查 SSH 密钥和部署脚本的权限设置。权限配置错误可能会导致未授权访问、数据泄露或被攻击。
遵循这些步骤后,你就能更好地保护部署流水线,并确保服务器安全。
测试并部署你的网站
执行一次测试部署
在将网站部署到生产环境之前,你应当始终先进行测试。测试部署可以帮助你尽早发现问题,并确保整个流程按预期运行。请按照以下步骤,从 GitHub 向你的私有服务器执行一次测试部署:
- 准备你的服务器。使用一个干净的 Linux 系统,例如 Ubuntu 22.04 或更高版本。确保服务器至少具备 4GB 内存和 2 个 CPU 核心,并确认它可以访问互联网。
- 从 GitHub 克隆你的部署仓库。使用正确的 SSH 密钥或 HTTPS 方式来保障访问安全。
- 选择你的安装方式。如果你想快速安装,可运行:
./scripts/install-fast.sh如果你需要自定义安装,请先准备好配置文件,然后使用 Helm 安装命令。
- 触发部署。向仓库推送一次变更,或者手动触发工作流或 Webhook。
- 查看服务器日志,确认部署脚本已经运行并成功更新文件。
提示:在将网站部署到生产环境之前,请务必先在预发布服务器上测试。这能够保护你的线上站点安全。
排查常见问题
在部署过程中,你可能会遇到一些常见问题。下表列出了常见错误、成因以及预防措施:
| 问题 | 错误信息 | 原因 | 预防措施 |
|---|---|---|---|
| 映射中发现重复键 | duplicate key found in mapping | YAML 解析器更新 | 在模板中使用唯一且描述清晰的命名 |
| 找不到 Secret | Secret not found or variable is empty | 语法错误 | 在模板中展示正确的上下文语法 |
| 矩阵策略错误 | Matrix not expanded, tests skipped | 无效的矩阵配置 | 在模板中提供一个可正常工作的矩阵示例 |
| 上下文语法错误 | Variable not interpolated, value is empty | 忘记使用 ${{ }} 包裹 | 在模板中展示所有上下文模式 |
| 模板过于复杂 | Contributor ignores template, issue incomplete | 包含 20 个以上字段 | 保持技能类模板简洁(最多 5-8 个字段) |
| 缺少必填字段 | Issue incomplete, missing key information | Markdown 模板缺少校验 | 使用带有 required: true 的 YAML 模板 |
| 工作流重复 | Wasted CI time, high maintenance overhead | 为 CI / CodeQL / dependency review 分别设置了独立工作流 | 在模板中提供整合方案 |
如果你遇到错误,请检查 YAML 文件中是否存在问题。确保所有 Secrets 和变量都已正确设置。查看部署日志通常可以帮助你快速定位原因。尽早修复这些小问题,会让你的部署流程更加顺畅可靠。
你应该经常测试部署流水线,并保持部署脚本的安全性。你还可以尝试一些更高级的工具,例如 AWS Code Deploy、Heroku、Zeit Now、Netlify、Travis CI、CircleCI、AWS ECS、Docker Swarm 和 Kubernetes。对于移动端项目,也可以使用 Bitrise 和 Firebase。为你的 GitHub 集成增加通知系统,可以帮助你更好地监控部署状态。这些工具能够帮助你管理 Git 工作流,并让你的云服务器保持最新。自动化检查、监控工具和可视化仪表盘,会为你带来更强的控制力与安全性。
