前言:最后一块拼图

您好!这篇文章终于是漫长系列的最后一篇。到目前为止,我们已经从自动部署系统的理论入手,实现了 FastAPI Webhook 服务器的核心逻辑,并构建了一个稳定的运行环境。

本系列之前的文章可以通过以下链接查看。

① 为什么要自己实现?

② 整体架构与流程设计

③ Staging 服务器环境设置与 FastAPI Webhook 服务器基础构建

④ 部署处理器详细及 Systemd 服务注册

但是,还有最后一步。目前我们的 FastAPI Webhook 服务器只在 8000 端口上运行,并且没有使用 HTTPS,这在安全上是有漏洞的。此外,GitHub 强烈建议使用公开域名和 HTTPS 连接。

在这一篇中,我们将完成最后的拼图,设置 Nginx 作为反向代理 将 FastAPI 服务器安全地暴露给外部,并通过 Let's Encrypt 应用免费 HTTPS,最终与 GitHub Webhook 进行集成,完成自动部署系统。

等一下,为什么选择 Nginx 而不是 Apache2 呢? Apache2 和 Nginx 是在服务器程序市场中占据一席之地的优秀 Web 服务器。 然而,像 FastAPI 这样的 异步 Web 框架 与 Nginx 更加契合。 Nginx 是以异步事件为基础设计的,可以最大限度地发挥 FastAPI 在高并发环境下的异步性能。 因此,FastAPI 社区强烈推荐将 Nginx 用于生产环境的 Web 服务器,本文也将围绕 Nginx 进行说明。

Nginx 安装与反向代理设置

为什么要使用 Nginx?

  1. 反向代理:像 FastAPI 这样的应用服务器并不是直接接收外部流量的。Nginx 作为反向代理,可以接收 Webhook 请求并安全地转发给 FastAPI 服务器。

  2. 安全性:Nginx 提供各种安全配置和 DDoS 攻击防护功能。

  3. HTTPS 应用:管理和应用 HTTPS 证书的任务由 Nginx 等 Web 服务器负责。

Nginx 安装与配置

通过 SSH 访问 Staging 服务器并安装 Nginx。假设读者已经具备一定的 Nginx 使用经验,因此本文将省略 Nginx 的安装方法、文件结构和工作原理的详细说明。

sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx # 重启时自动启动
sudo systemctl start nginx # 启动 nginx
sudo systemctl status nginx # 检查是否处于活动状态

接下来,我们编写 Nginx 配置文件,以转发到我们的 FastAPI Webhook 服务器。假设我们使用域名 deployer.example.com。以下是配置示例。

#/etc/nginx/sites-available/deployer.example.com

# HTTP 请求重定向到 HTTPS
server {
    listen 80;
    server_name deployer.example.com;
    return 308 https://$host$request_uri;
}

# HTTPS 请求处理
server {
    listen 443 ssl;
    server_name deployer.example.com;

    # SSL 证书路径配置
    ssl_certificate /etc/letsencrypt/live/deployer.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/deployer.example.com/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

  • HTTP 80 端口设置server_namedeployer.example.comlisten 80 代码块通过 return 308 https://$host$request_uri; 命令将所有进入的 HTTP 请求永久重定向到 HTTPS。

  • HTTPS 443 端口设置listen 443 ssl; 代码块处理 HTTPS 请求。

  • ssl_certificate & ssl_certificate_key:假设我们已经通过 Let's Encrypt 获得证书,该代码块用于指定颁发的 SSL 证书和密钥文件的路径,该路径由 certbot 自动生成。

  • location / 代码块:用于将转到 HTTPS 的请求转发到我们的 FastAPI 服务器(http://127.0.0.1:8000)的反向代理设置。

重新启动 Nginx 后,将会安全的处理所有 Webhook 请求。

# 将配置文件符号链接到 sites-enabled 目录
sudo ln -s /etc/nginx/sites-available/deployer.example.com /etc/nginx/sites-enabled/

# 检查 Nginx 配置文件语法错误。
sudo nginx -t

# 重启 Nginx 以应用更改。
sudo systemctl restart nginx

应用 HTTPS (Let's Encrypt + Certbot)

出于安全原因,GitHub Webhook 强烈建议使用 HTTPS 通信。Let's Encrypt 是一个提供免费 SSL/TLS 证书的非营利性认证机构,而 Certbot 是一个优秀的工具,用于自动化证书的颁发和更新。这里将省略安装方法。

成功后,请在浏览器中访问 https://deployer.example.com,查看 FastAPI 的 API 文档(.../docs)或 / 端点。如果看到 Webhook server is running! 消息,则说明 Nginx 和 HTTPS 设置成功完成。

GitHub Webhook 最终集成与测试

现在所有准备工作都已完成。让我们将所构建的自动部署系统连接到 GitHub 仓库。

  1. 访问 GitHub 仓库:转到要应用自动部署的项目的 GitHub 仓库。

  2. Webhook 设置:点击顶部菜单中的 Settings -> 左侧菜单中点击 Webhooks

  3. 添加 Webhook:点击 Add webhook 按钮,输入以下信息。

    • Payload URL:输入应用了 Nginx 和 HTTPS 的 Webhook 服务器地址(例如:https://deployer.example.com/webhook)。

    • Content type:选择 application/json

    • Secret:准确复制并粘贴在第 3 篇中设置的 ~/projects/webhook_server/.env 文件中的 GITHUB_WEBHOOK_SECRET 的值。

    • Which events would you like to trigger this webhook?:选择 Just the push event

    • Active:确保复选框已启用。

  4. 保存:点击 Add webhook 按钮以保存 Webhook。

GitHub Webhook 设置截图

如果 Webhook 正常注册,在 Recent Deliveries 部分将会出现绿色勾选,确认测试请求已成功发送。

现在进行最终测试。

  1. 在本地修改代码:稍微修改项目代码,并进行 Git 提交和推送。

  2. 检查状态

    • 在 GitHub Webhook 设置页面的 Recent Deliveries 中检查刚才发送的推送的 Webhook 是否成功(绿色勾选)。

    • 通过 SSH 登录到 Staging 服务器,使用 sudo journalctl -u github-webhook-deployer.service -f 命令查看实时日志。如果看到 Git pull successfulDeployment task finished 等消息,则表示成功。

    • 检查已部署的 Docker 容器的状态,确认最新代码是否已反映。

总结:自动部署系统完成!

恭喜!您成功构建了一个完整的 CI/CD 管道,从本地开发环境到 GitHub,再到自建的 Staging 服务器。

通过这个系列,我们完成了以下所有内容。

  • 理解了为什么要自己构建基于 Webhook 的自动部署系统。

  • 设计并实现了基于 FastAPI 的 Webhook 服务器架构。

  • 学习了如何稳定地使用 Systemd 运行服务。

  • 通过 Nginx 和 HTTPS 设置加强了安全性。

  • 最终成功与 GitHub 集成,实现了全自动化。

现在只要您推送代码,服务器就会自动反映最新代码,不再需要您的手动干预。您可以在此基础上添加更复杂的部署逻辑或集成通知功能等,自由发挥。

感谢您陪伴我走过这段漫长旅程!