当你把代码从 GitHub 自动部署到自己的服务器时,可以节省时间并避免出错。部署自动化能够带来更快的反馈,也有助于团队更高效地协作。借助 GitHub Actions、Webhook 和部署脚本等工具,你可以减少人为失误,让整个流程更加稳定可靠。即使你只掌握了 GitHub 和服务器管理的基础知识,也能搭建这套工作流,并很快看到改进效果。

关键要点

  • 将代码部署自动化可以节省时间并减少错误。使用 GitHub Actions 和 Webhook 等工具,可以让流程更加顺畅。
  • 准备好必要的工具和账户,包括 GitHub 仓库、云服务器以及部署脚本。这些基础配置是成功实现自动化的关键。
  • 通过 SSH 密钥实现免密访问,保障服务器安全。这能确保只有受信任的系统可以连接到你的服务器。
  • 在正式上线前,先在预发布服务器上测试部署流程。这样可以及早发现问题,保护生产环境。
  • 使用 GitHub Secrets 安全存储敏感信息。这可以让密码和密钥不会暴露在工作流文件中。

自动部署的前置条件

所需工具与账户

在开始设置自动部署之前,你需要准备一些必要的工具和账户。它们将帮助你把 GitHub 上的代码连接到服务器,并让整个流程更加顺畅。

  1. 在线远程仓库:你需要一个 GitHub 账户,并拥有一个存放项目代码的仓库。
  2. 本地 Git 仓库:在你的电脑上配置一个本地 Git 仓库,用于管理代码变更。
  3. 云服务器:选择一个云服务器提供商,例如 Amazon EC2 或 Rackspace。你的网站或应用将运行在这里。
  4. 部署脚本:编写一个部署脚本,例如 deploy.php,用于拉取 GitHub 上的最新代码。
  5. 服务器上安装 Git:确保你的服务器已安装 Git,并且版本为最新。
  6. SSH 密钥设置:在服务器上生成 SSH 密钥,以实现与 GitHub 的安全免密通信。
  7. 将 SSH 公钥添加到 GitHub:把服务器的 SSH 公钥添加到你的 GitHub 账户中,以便服务器能够访问仓库。
  8. 设置 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 监听器配置流程:

  1. 将你的 Git 仓库分别克隆到生产环境和预发布环境对应的目录中。
  2. 为每个环境创建 Bash 脚本,并赋予这些脚本执行权限,以便自动运行。
  3. 编写处理 Webhook 事件的代码。很多开发者会在 Node.js 中使用 github-webhook-handler 包,但你也可以使用 PHP 或 Python。
  4. 在 GitHub 仓库设置中配置 Webhook URL。选择用于触发 Webhook 的事件,例如 push 或 pull request。
  5. 测试并验证你的配置。你可以使用 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:

  1. 编写处理 Webhook 事件的代码,并确保你的服务器拥有一个 GitHub 可以访问的公网 URL。
  2. 如果你想简化事件处理流程,可以使用像 github-webhook-handler 这样的包。
  3. 运行你的服务程序,让它开始监听传入的 Webhook 请求。
  4. 进入 GitHub 仓库设置页面,新增一个 Webhook,并填写监听脚本的 URL。
  5. 选择应该触发 Webhook 的事件,例如 push 事件或 pull request。

在使用 Webhook 时,安全性非常重要。你需要确保只有 GitHub 才能触发服务器上的部署。以下是一些关键的安全注意事项:

安全注意事项说明
使用密钥进行验证为你的 Webhook 添加一个密钥,以帮助确认请求确实来自 GitHub。
Webhook URL 的可访问性请妥善保护你的 Webhook URL,不要随意公开,以防止未经授权的访问。
使用 HTTPS配置 HTTPS,以加密 GitHub 与服务器之间的通信。

注意:如果你使用了密钥,请同步更新监听脚本,以校验传入请求的签名。这会增加一层额外的安全保护。

完成这些步骤后,每次你向仓库推送代码,服务器都会自动部署最新版本。这样的配置可以节省时间,并减少手动操作带来的风险。

安全的服务器访问与 SSH 密钥

配置安全访问机制,是任何自动化部署流程中都非常关键的一部分。你需要确保只有受信任的用户和系统能够连接到服务器。使用 SSH 密钥可以帮助你实现安全、免密的连接。

生成 SSH 密钥

你可以通过生成 SSH 密钥,让部署流程安全地连接到服务器。请按以下步骤为部署用户配置 SSH 密钥:

  1. 在本地机器上生成一对新的 SSH 密钥:
    ssh-keygen -t ed25519 -f ~/.ssh/blog_deployer
  2. 在服务器上创建一个专门用于部署的用户:
    useradd blog-deployer
  3. 锁定该用户的密码,防止其通过密码登录:
    passwd -l blog-deployer
  4. 为新用户创建一个 .ssh 目录:
    mkdir -p /home/blog-deployer/.ssh
  5. 将公钥添加到 authorized_keys 文件中:
    nano /home/blog-deployer/.ssh/authorized_keys
  6. 修改主目录的所有权:
    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 向你的私有服务器执行一次测试部署:

  1. 准备你的服务器。使用一个干净的 Linux 系统,例如 Ubuntu 22.04 或更高版本。确保服务器至少具备 4GB 内存和 2 个 CPU 核心,并确认它可以访问互联网。
  2. 从 GitHub 克隆你的部署仓库。使用正确的 SSH 密钥或 HTTPS 方式来保障访问安全。
  3. 选择你的安装方式。如果你想快速安装,可运行:
    ./scripts/install-fast.sh

    如果你需要自定义安装,请先准备好配置文件,然后使用 Helm 安装命令。

  4. 触发部署。向仓库推送一次变更,或者手动触发工作流或 Webhook。
  5. 查看服务器日志,确认部署脚本已经运行并成功更新文件。

提示:在将网站部署到生产环境之前,请务必先在预发布服务器上测试。这能够保护你的线上站点安全。

排查常见问题

在部署过程中,你可能会遇到一些常见问题。下表列出了常见错误、成因以及预防措施:

问题错误信息原因预防措施
映射中发现重复键duplicate key found in mappingYAML 解析器更新在模板中使用唯一且描述清晰的命名
找不到 SecretSecret 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 informationMarkdown 模板缺少校验使用带有 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 工作流,并让你的云服务器保持最新。自动化检查、监控工具和可视化仪表盘,会为你带来更强的控制力与安全性。