Files
panda db867dcbe5
Deploy to Staging / deploy (push) Has been cancelled
Conflict detector / main (push) Has been cancelled
Lint Backend / lint-backend (push) Has been cancelled
Playwright Tests / changes (push) Has been cancelled
Test Backend / test-backend (push) Has been cancelled
Test Docker Compose / test-docker-compose (push) Has been cancelled
Playwright Tests / test-playwright (1, 4) (push) Has been cancelled
Playwright Tests / test-playwright (2, 4) (push) Has been cancelled
Playwright Tests / test-playwright (3, 4) (push) Has been cancelled
Playwright Tests / test-playwright (4, 4) (push) Has been cancelled
Playwright Tests / merge-playwright-reports (push) Has been cancelled
Playwright Tests / alls-green-playwright (push) Has been cancelled
Issue Manager / issue-manager (push) Has been cancelled
中文汉化
2025-12-18 09:40:41 +08:00

317 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](https://docs.docker.com/engine/install/)Docker Engine,而非 Docker Desktop)。
## 公共 Traefik
我们需要一个 Traefik 代理来处理外部请求以及 HTTPS 证书。
下面的步骤只需执行一次。
### Traefik 的 Docker Compose
* 在远程服务器上创建一个目录,用来存放 Traefik 的 Docker Compose 文件:
```bash
mkdir -p /root/code/traefik-public/
```
在本地终端中使用 `rsync` 将 Traefik 的 Docker Compose 文件拷贝到服务器:
```bash
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,即便它们都在同一台物理服务器上。
在远程服务器中创建该网络:
```bash
docker network create traefik-public
```
### Traefik 环境变量
Traefik 的 Docker Compose 文件在启动前需要若干环境变量,你可以在远程服务器终端中通过以下命令设置:
* 为 HTTP Basic Auth 创建用户名,例如:
```bash
export USERNAME=admin
```
* 创建 Basic Auth 密码对应的环境变量,例如:
```bash
export PASSWORD=changethis
```
* 使用 openssl 生成该密码的哈希值并保存到环境变量中:
```bash
export HASHED_PASSWORD=$(openssl passwd -apr1 $PASSWORD)
```
可以通过打印检查哈希是否已生成:
```bash
echo $HASHED_PASSWORD
```
* 创建保存服务器主域名的环境变量,例如:
```bash
export DOMAIN=fastapi-project.example.com
```
* 创建保存 Let's Encrypt 邮箱的环境变量,例如:
```bash
export EMAIL=admin@example.com
```
**注意**:邮箱不能是 `@example.com` 这样的占位域名,需要使用真实邮箱。
### 启动 Traefik Docker Compose
在远程服务器上进入存放 Traefik Docker Compose 文件的目录:
```bash
cd /root/code/traefik-public/
```
在环境变量已经设置、`docker-compose.traefik.yml` 已就位的情况下,启动 Traefik:
```bash
docker compose -f docker-compose.traefik.yml up -d
```
## 部署 FastAPI 项目
在 Traefik 准备好之后,就可以使用 Docker Compose 部署 FastAPI 项目。
**提示**:你也可以直接跳到后面的「使用 GitHub Actions 持续部署」部分。
## 环境变量
在部署前,需要设置若干环境变量。
设置 `ENVIRONMENT`,默认是 `local`(开发环境),部署到服务器时可以设置为 `staging``production`,例如:
```bash
export ENVIRONMENT=production
```
设置 `DOMAIN`,本地默认是 `localhost`,在部署时应改为你的实际域名,例如:
```bash
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](https://github.com/tiangolo/latest-changes) GitHub Action,根据合并的 PR 自动生成发布日志。它需要一个个人访问令牌(PAT),具体可见其文档。
* `SMOKESHOW_AUTH_KEY`:用于 [Smokeshow](https://github.com/samuelcolvin/smokeshow) 发布测试覆盖率报告,同样需要按其说明生成一个(免费的)密钥。
### 生成密钥
`.env` 文件中的一些环境变量默认为 `changethis`,需要改为真正的随机密钥。
可以使用下面的命令生成密钥:
```bash
python -c "import secrets; print(secrets.token_urlsafe(32))"
```
复制输出内容并用作密码 / 密钥;需要多个密钥时多执行几次即可。
### 使用 Docker Compose 部署
环境变量准备就绪后,可以使用 Docker Compose 部署:
```bash
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 创建一个用户,例如:
```bash
sudo adduser github
```
*`github` 用户添加 Docker 权限:
```bash
sudo usermod -aG docker github
```
* 临时切换为 `github` 用户:
```bash
sudo su - github
```
* 进入 `github` 用户的 home 目录:
```bash
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` 用户退出,回到之前的用户:
```bash
exit
```
此时你会回到之前的用户及其当前目录。
* 在能访问 `github` 用户 home 目录之前,你需要切换成 `root` 用户(如果已经是则可略过):
```bash
sudo su
```
*`root` 用户下,进入 `github` 用户 home 下的 `actions-runner` 目录:
```bash
cd /home/github/actions-runner
```
* 安装 Runner 为服务,并指定服务用户为 `github`
```bash
./svc.sh install github
```
* 启动该服务:
```bash
./svc.sh start
```
* 查看服务状态:
```bash
./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_PRODUCTION`
* `DOMAIN_STAGING`
* `STACK_NAME_PRODUCTION`
* `STACK_NAME_STAGING`
* `EMAILS_FROM_EMAIL`
* `FIRST_SUPERUSER`
* `FIRST_SUPERUSER_PASSWORD`
* `POSTGRES_PASSWORD`
* `SECRET_KEY`
* `LATEST_CHANGES`
* `SMOKESHOW_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`