10 KiB
FastAPI 项目 - 部署(Deployment)
你可以使用 Docker Compose 将本项目部署到远程服务器。
本项目假定你已经有一个 Traefik 代理,用于处理对外的 HTTP/HTTPS 流量以及证书管理。
你可以使用 CI/CD(持续集成与持续部署)系统自动部署,本项目已经提供了 GitHub Actions 的示例配置。
在此之前,你需要完成一些基础配置。🤓
部署前准备
- 准备一台可访问的远程服务器。
- 将你的域名 DNS 记录解析到该服务器的 IP。
- 为该域名配置通配符子域名(Wildcard),例如
*.fastapi-project.example.com,以便为不同服务使用不同子域名,如dashboard.fastapi-project.example.com、api.fastapi-project.example.com、traefik.fastapi-project.example.com、adminer.fastapi-project.example.com等;同时也便于配置staging环境,比如dashboard.staging.fastapi-project.example.com、adminer.staging.fastapi-project.example.com等。 - 在远程服务器上安装并配置 Docker(Docker Engine,而非 Docker Desktop)。
公共 Traefik
我们需要一个 Traefik 代理来处理外部请求以及 HTTPS 证书。
下面的步骤只需执行一次。
Traefik 的 Docker Compose
- 在远程服务器上创建一个目录,用来存放 Traefik 的 Docker Compose 文件:
mkdir -p /root/code/traefik-public/
在本地终端中使用 rsync 将 Traefik 的 Docker Compose 文件拷贝到服务器:
rsync -a docker-compose.traefik.yml root@your-server.example.com:/root/code/traefik-public/
Traefik 公共网络
Traefik 会期望有一个名为 traefik-public 的 Docker “公共网络”,用来与各个应用 stack 通信。
通过这种方式,可以用一个公共 Traefik 代理对外处理 HTTP/HTTPS 流量,其后可以挂载一个或多个不同域名的应用 stack,即便它们都在同一台物理服务器上。
在远程服务器中创建该网络:
docker network create traefik-public
Traefik 环境变量
Traefik 的 Docker Compose 文件在启动前需要若干环境变量,你可以在远程服务器终端中通过以下命令设置:
- 为 HTTP Basic Auth 创建用户名,例如:
export USERNAME=admin
- 创建 Basic Auth 密码对应的环境变量,例如:
export PASSWORD=changethis
- 使用 openssl 生成该密码的哈希值并保存到环境变量中:
export HASHED_PASSWORD=$(openssl passwd -apr1 $PASSWORD)
可以通过打印检查哈希是否已生成:
echo $HASHED_PASSWORD
- 创建保存服务器主域名的环境变量,例如:
export DOMAIN=fastapi-project.example.com
- 创建保存 Let's Encrypt 邮箱的环境变量,例如:
export EMAIL=admin@example.com
注意:邮箱不能是 @example.com 这样的占位域名,需要使用真实邮箱。
启动 Traefik Docker Compose
在远程服务器上进入存放 Traefik Docker Compose 文件的目录:
cd /root/code/traefik-public/
在环境变量已经设置、docker-compose.traefik.yml 已就位的情况下,启动 Traefik:
docker compose -f docker-compose.traefik.yml up -d
部署 FastAPI 项目
在 Traefik 准备好之后,就可以使用 Docker Compose 部署 FastAPI 项目。
提示:你也可以直接跳到后面的「使用 GitHub Actions 持续部署」部分。
环境变量
在部署前,需要设置若干环境变量。
设置 ENVIRONMENT,默认是 local(开发环境),部署到服务器时可以设置为 staging 或 production,例如:
export ENVIRONMENT=production
设置 DOMAIN,本地默认是 localhost,在部署时应改为你的实际域名,例如:
export DOMAIN=fastapi-project.example.com
你还可以设置以下变量:
PROJECT_NAME:项目名称,用于 API 文档及邮件内容中展示。STACK_NAME:在 Docker Compose 中使用的 stack 名称,也用于标签与项目名。该值在staging、production等环境中应各不相同。一个常见做法是将域名中的点替换为短横线,例如fastapi-project-example-com与staging-fastapi-project-example-com。BACKEND_CORS_ORIGINS:允许的 CORS 源列表,使用逗号分隔。SECRET_KEY:FastAPI 项目的密钥,用于签发 token 等安全相关操作。FIRST_SUPERUSER:首个超级用户的邮箱地址,该用户可以创建其他用户。FIRST_SUPERUSER_PASSWORD:首个超级用户的密码。SMTP_HOST:SMTP 服务器地址,用于发邮件(如 Mailgun、Sparkpost、Sendgrid 等提供的地址)。SMTP_USER:SMTP 用户名。SMTP_PASSWORD:SMTP 密码。EMAILS_FROM_EMAIL:发件邮箱地址。POSTGRES_SERVER:PostgreSQL 服务器主机名。使用 Docker Compose 时可以保持默认值db,除非你改为使用第三方数据库服务。POSTGRES_PORT:PostgreSQL 端口,通常保持默认即可。POSTGRES_PASSWORD:PostgreSQL 密码。POSTGRES_USER:PostgreSQL 用户名,一般使用默认值即可。POSTGRES_DB:本应用使用的数据库名称,默认app。SENTRY_DSN:如果接入了 Sentry,这里填入 DSN。
GitHub Actions 环境变量
有一些环境变量只在 GitHub Actions 中使用,可以按需配置:
LATEST_CHANGES:用于 latest-changes GitHub Action,根据合并的 PR 自动生成发布日志。它需要一个个人访问令牌(PAT),具体可见其文档。SMOKESHOW_AUTH_KEY:用于 Smokeshow 发布测试覆盖率报告,同样需要按其说明生成一个(免费的)密钥。
生成密钥
.env 文件中的一些环境变量默认为 changethis,需要改为真正的随机密钥。
可以使用下面的命令生成密钥:
python -c "import secrets; print(secrets.token_urlsafe(32))"
复制输出内容并用作密码 / 密钥;需要多个密钥时多执行几次即可。
使用 Docker Compose 部署
环境变量准备就绪后,可以使用 Docker Compose 部署:
docker compose -f docker-compose.yml up -d
在生产环境中,一般不希望加载 docker-compose.override.yml 中的开发用覆盖配置,因此这里显式指定只使用 docker-compose.yml。
持续部署(CD)
你可以使用 GitHub Actions 自动部署你的项目。😎
可以为多个环境配置不同的部署流程。
本项目中已经预置了 staging 与 production 两个环境。🚀
安装 GitHub Actions Runner
- 在远程服务器上为 GitHub Actions 创建一个用户,例如:
sudo adduser github
- 为
github用户添加 Docker 权限:
sudo usermod -aG docker github
- 临时切换为
github用户:
sudo su - github
- 进入
github用户的 home 目录:
cd
-
按照官方文档安装 GitHub Action 自托管 Runner:
https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository -
在安装过程中,当被询问标签(labels)时,为 Runner 添加对应环境的标签,例如
production;也可以在后续再补充标签。
安装完成后,官方文档会让你手动运行一个命令以启动 Runner。但一旦你断开终端连接或进程退出,Runner 就会停止。
为了确保服务器重启后 Runner 仍能自动运行,建议将其安装为服务。具体步骤如下:
- 从
github用户退出,回到之前的用户:
exit
此时你会回到之前的用户及其当前目录。
- 在能访问
github用户 home 目录之前,你需要切换成root用户(如果已经是则可略过):
sudo su
- 在
root用户下,进入github用户 home 下的actions-runner目录:
cd /home/github/actions-runner
- 安装 Runner 为服务,并指定服务用户为
github:
./svc.sh install github
- 启动该服务:
./svc.sh start
- 查看服务状态:
./svc.sh status
更多细节可参考官方文档:
「Configuring the self-hosted runner application as a service」
https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service
配置 Secrets
在 GitHub 仓库中,为部署需要的环境变量配置 Secrets,包括前面提到的 SECRET_KEY 等。可参考官方文档:
「Using secrets in GitHub Actions」
https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository
当前的 GitHub Actions 工作流期望存在以下 Secrets:
DOMAIN_PRODUCTIONDOMAIN_STAGINGSTACK_NAME_PRODUCTIONSTACK_NAME_STAGINGEMAILS_FROM_EMAILFIRST_SUPERUSERFIRST_SUPERUSER_PASSWORDPOSTGRES_PASSWORDSECRET_KEYLATEST_CHANGESSMOKESHOW_AUTH_KEY
GitHub Actions 部署工作流
在 .github/workflows 目录中已经包含了一些用于部署到不同环境(基于 Runner 标签)的 GitHub Actions 工作流:
staging:在推送(或合并)到master分支后触发。production:在发布 Release 后触发。
如果你需要更多环境,可以以上述工作流为模板进行扩展。
URLs
下面示例中出现的 fastapi-project.example.com 请替换为你自己的域名。
主 Traefik 控制台
Traefik UI:https://traefik.fastapi-project.example.com
生产环境(Production)
前端:https://dashboard.fastapi-project.example.com
后端 API 文档:https://api.fastapi-project.example.com/docs
后端 API 基础地址:https://api.fastapi-project.example.com
Adminer:https://adminer.fastapi-project.example.com
预发布环境(Staging)
前端:https://dashboard.staging.fastapi-project.example.com
后端 API 文档:https://api.staging.fastapi-project.example.com/docs
后端 API 基础地址:https://api.staging.fastapi-project.example.com
Adminer:https://adminer.staging.fastapi-project.example.com