引言:CI/CD 和自动部署的重要性

高效的开发工作流程需要自动部署,即 CI/CD(持续集成/持续交付),这已不再是选择,而是必需。如果将代码推送到 GitHub 时,构建-测试-部署的过程能自动完成,将大大提高开发生产力。

实现这种自动部署的方法有很多,但可通过 GitHub 自身提供的 GitHub Actions 或利用 GitHub 的 Webhook 功能直接实现部署逻辑。

为什么要自己实现 Webhook 而不是使用 GitHub Actions?

GitHub 猫把 Webhook 飞机扔给 Tux

GitHub Actions 无疑是一个强大且方便的 CI/CD 工具。只需几行 YAML 文件即可定义复杂的工作流程,并通过各种动作市场自动化构建、测试和部署等多个过程。对于大多数项目而言,GitHub Actions 的确是一个出色的选择。

然而,在所有情况下,GitHub Actions 并不是最佳选择。特别是对于以下情况的开发者来说,利用 GitHub Webhook 直接实现方式可能更具吸引力。

  • 对成本敏感的个人开发者或小型团队: GitHub Actions 在公共库中几乎无限免费,但在私有库中,超出一定数量的免费配额(分钟和存储)后会收费。如果希望完全避免意外的费用生成,自己实现就是答案。

  • 正在运营自有阶段性服务器(如 Raspberry Pi 5)的开发者: 如果已经拥有物理服务器(包括 VPS、云实例),那么充分利用自有服务器的资源,而不必使用 GitHub 的虚拟环境(Runner)会更高效。在自己的服务器上直接接收和部署代码的方式更具成本效益,在资源利用方面也更具优势。

  • 希望对部署逻辑进行完全控制和自由的开发者: GitHub Actions 使用的是标准化的工作流程和动作,但直接实现 Webhook 可以完全按照自己的意愿设计和控制部署脚本的每个部分。当需要特定环境的复杂自定义逻辑,或与已构建的管道完美集成时,此方式具有优势。

在本系列中,我们将详细讨论如何利用 GitHub Webhook 在自己的服务器上直接实现部署逻辑。我们面向 Python 开发者,特别是将使用简单而强大的网页框架 FastAPI 来构建 Webhook 端点。DRF(Django REST Framework)也是一个不错的选择,但由于只是处理 Webhook 请求的一种非常轻量的逻辑,FastAPI 是更优选择。就像去超市买东西,不必非得开跑车,一辆小轿车就足够了。

构建自动部署系统所需的基本准备

实际的实现将在下一篇开始,本篇我们整理了顺利进行所需的准备工作。

  1. GitHub 仓库:

    • 需要一个包含 Python 项目的 GitHub 仓库(公开或私有均可)。

    • 每当向该仓库推送代码时,部署将开始。

  2. 阶段性服务器(自托管服务器):

    • 需要实际进行部署的服务器。Raspberry Pi 5 、个人 VPS(虚拟私有服务器)、云实例(如 AWS EC2,GCP Compute Engine 等)均可。

    • 必须通过 公用 IP 地址或域名,让外部(如 GitHub)可以访问(请注意防火墙设置)。

    • 建议使用 Ubuntu Server 等 Linux 环境。

    • 安装 Docker:部署的应用程序必须能够在 Docker 容器中构建或运行,因此必须提前在服务器上安装 Docker。

  3. Python 开发环境:

    • 在阶段性服务器上需安装 Python 3.8 或更高版本(推荐使用虚拟环境)。
  4. Git:

    • 在阶段性服务器上需安装 Git。从 GitHub 仓库获取最新代码将使用到 git pull 命令。
  5. FastAPI 和 Uvicorn:

    • 需要用于实现 Python Webhook 端点的框架 FastAPI 和 ASGI 服务器 Uvicorn。将在下一篇中讨论安装和基本设置。
  6. SSH 密钥:

    • 需要设置 SSH 密钥 以便安全地访问 GitHub 仓库并获取代码。大部分人应该已经在自己账号上注册了 SSH 密钥。(尚未注册的人请去 GitHub 注册。使用部署密钥 Deploy key 是常见做法)。
  7. 对网络服务器(Nginx 或 Apache2)及域名/HTTPS 设置的理解:

    • GitHub Webhook 通常建议使用 HTTPS 进行安全通信。因此,强烈建议提前准备一个如 deployer.example.com 这样的 子域名,并为该域名申请 HTTPS 证书(例如通过 Let's Encrypt 获取免费证书)

    • 我想应该没有人会将 FastAPI 应用程序直接通过端口转发连接到互联网 ISP 的路由器,但如果真有这种情况,为了安全起见,我再补充说明,应用程序一般不直接暴露在外,而是使用 Nginx 或 Apache2 作为 反向代理 将 Webhook 请求转发到 FastAPI 应用程序。这样做更为安全,确保了服务器程序能够反向代理进行连接。对这一点的基本理解和设置经验将大有帮助。

  8. 对 Systemd 服务的理解(可选但推荐):

    • 这个 FastAPI Webhook 服务器必须始终驻留并运行在阶段性服务器上。为此,建议将其注册为 Systemd 服务,以便在服务器重启时自动启动,便于进行服务管理(启动/停止/重启)。

    • 注意: 在 Docker 容器内部直接执行 gitdocker 命令的复杂部署逻辑不符合容器设计目的,也需要复杂的设置如 docker-in-dockerdocker-out-of-docker ,对安全性也不利。如果服务器上已经安装了 gitdocker,那么将 FastAPI Webhook 服务器轻量启动为 Systemd 服务,在部署脚本中直接使用系统的 gitdocker 命令将更高效更简洁。本系列将以这种方式为中心进行说明。


现在一切准备就绪。下一篇将详细讨论如何在准备好的阶段性服务器上构建 FastAPI Webhook 端点,并设置 GitHub Webhook 实现首次自动部署。敬请期待!