Level 36 / 阅读练习

FastAPI 项目配置、多环境和部署上线

理解 .env、多环境配置、Docker Compose、Nginx、HTTPS、健康检查、日志和上线检查。

Progress

阅读中

0/2 步完成 / 阅读后完成练习才算通关

Practice

本关怎么过

  • 读完正文后确认完成阅读
  • 完成 1 道选择题练习
  • 答错时看解释,再回到正文补理解

一句话:多环境和部署上线就是让同一套 FastAPI 代码,在本地、测试环境、生产环境都能用正确配置稳定跑起来。

本篇学完你会什么:理解 .env、环境变量、dev/test/prod、Docker Compose、Nginx、HTTPS、健康检查、日志和上线前检查这些部署必备概念。

1. 为什么不能只会本地运行

本地运行通常是:

uvicorn app.main:app --reload

这只能说明代码能在你电脑上跑。

真实上线还要考虑:

数据库地址是不是生产库
JWT_SECRET 有没有换成强密钥
Redis 密码有没有配置
前端请求能不能转到后端
接口挂了有没有健康检查
日志去哪看
HTTPS 有没有配置

部署不是“把代码丢到服务器”,而是让服务在另一个环境里可重复、可检查、可恢复地运行。

2. 多环境到底是什么

常见三套环境:

环境用途特点
dev 本地开发写代码、调试可以热更新,数据可重建
test 测试环境给自己或团队验证接近生产,但允许重置
prod 生产环境给真实用户使用稳定、安全、可备份

同一套代码,配置不同:

配置devtestprod
数据库本地 Docker测试库生产库
Redis本地 Redis测试 Redis生产 Redis
JWT_SECRET开发密钥测试密钥强随机密钥
日志级别debuginfoinfo/warning
CORSlocalhost测试域名正式域名

3. 配置应该怎么分

代码里放默认结构,环境变量里放真实值。

app/core/config.py

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    APP_ENV: str = "development"
    DATABASE_URL: str
    REDIS_URL: str
    JWT_SECRET: str
    CORS_ORIGINS: list[str] = []
    LOG_LEVEL: str = "INFO"

    class Config:
        env_file = ".env"


settings = Settings()

这里的 env_file = ".env" 可以先理解成本地兜底配置:你直接运行 uvicorn app.main:app --reload 时,应用会从 .env 读配置。

到了 Docker Compose 里,env_file: .env.prod 是 Compose 先读取 .env.prod,再把里面的值注入到容器环境变量里。Pydantic Settings 会优先读取真实环境变量,所以容器里拿到的是 Compose 注入的生产配置,而不是本地 .env

如果你想做得更严格,也可以用 ENV_FILE=.env.prod 这类变量动态决定加载哪个文件;本篇先用更容易理解的写法。

运行方式配置来源适合场景
本地直接 uvicorn应用读取 .env自己开发调试
Docker Compose 测试/生产Compose 读取 .env.test.env.prod 后注入容器接近真实部署
正式生产密钥服务器环境变量或密钥管理服务避免敏感信息落在仓库里

重点规则:

内容能不能提交
.env.example可以,放示例
.env不要,放本地真实配置
.env.prod通常不要提交,或只放在服务器安全位置
JWT_SECRET不能用默认值
数据库密码不能写死在代码里

4. .env.example.env.test.env.prod 怎么用

.env.example 给别人看需要哪些配置:

APP_ENV=development
DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/appdb
REDIS_URL=redis://localhost:6379/0
JWT_SECRET=change-me
CORS_ORIGINS=["http://localhost:3000"]
LOG_LEVEL=INFO

.env.test 可以接测试服务:

APP_ENV=test
DATABASE_URL=postgresql+asyncpg://postgres:testpass@test-db:5432/appdb
REDIS_URL=redis://test-redis:6379/0
JWT_SECRET=test-random-secret
CORS_ORIGINS=["https://test.example.com"]
LOG_LEVEL=INFO

.env.prod 放生产配置:

APP_ENV=production
DATABASE_URL=postgresql+asyncpg://app:strongpass@prod-db:5432/appdb
REDIS_URL=redis://:strongpass@prod-redis:6379/0
JWT_SECRET=very-long-random-secret
CORS_ORIGINS=["https://example.com"]
LOG_LEVEL=WARNING

大白话:.env.example 是清单,.env.prod 是钥匙。清单可以给别人看,钥匙不要乱放。

5. Docker Compose 怎么组织服务

一个后端常见需要:

api FastAPI 服务
db PostgreSQL
redis 缓存
nginx 反向代理

简化版:

services:
  api:
    build: .
    env_file:
      - .env.prod
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: appdb
      POSTGRES_USER: app
      POSTGRES_PASSWORD: strongpass
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
      interval: 5s
      timeout: 5s
      retries: 10

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

注意:生产环境数据库密码不要直接写在公开仓库里。这里是为了讲结构,真实项目要用服务器环境变量、密钥管理或安全的部署文件。

再记一次配置优先级:应用里的 .env 只是本地默认值;Docker Compose 的 env_file 会把变量放进容器环境,容器环境里的值会优先被读取。

6. Nginx 在前面做什么

Nginx 像门口接待员:

用户访问 https://example.com
  ↓
Nginx 接住请求
  ↓
/api 转给 FastAPI
静态页面直接返回

常见配置思路:

location /api/ {
  proxy_pass http://api:8000/api/;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
}

Nginx 常做:

能力大白话
反向代理把请求转给后端
静态资源直接返回前端构建文件
HTTPS处理证书
gzip压缩响应
上传大小限制控制大文件

7. HTTPS 和域名先理解什么

域名解决:

用户记 example.com,不用记服务器 IP

HTTPS 解决:

浏览器和服务器之间的数据加密传输

正式系统建议:

  1. 域名解析到服务器。
  2. Nginx 接收 80/443。
  3. 用证书启用 HTTPS。
  4. HTTP 自动跳转 HTTPS。

初学不用一开始深挖证书原理,先知道:登录、token、后台系统上线时应该用 HTTPS。

8. 日志和健康检查怎么做

健康检查接口:

@app.get("/health")
async def health():
    return {"status": "ok"}

更完整一点可以检查数据库:

@app.get("/health")
async def health(db: AsyncSession = Depends(get_db)):
    await db.execute(text("SELECT 1"))
    return {"status": "ok", "database": "ok"}

日志至少要记录:

日志用途
启动日志确认服务是否启动
请求错误排查 500
登录失败发现异常尝试
关键操作谁修改了重要数据

不要打印:

明文密码
完整 token
身份证、手机号等敏感信息

9. 上线流程建议

最稳的顺序:

1. 本地跑通测试
2. 构建 Docker 镜像
3. 上传或拉取代码到服务器
4. 准备 .env.prod
5. docker compose config 检查配置
6. docker compose up -d 启动
7. 执行数据库迁移
8. 检查 /health
9. 检查 Nginx 代理
10. 检查前端页面和接口联调

上线后不要只看“容器启动了”。要真的访问:

/health
/docs 或关键接口
登录
用户列表
新增/编辑/删除

10. 常见错误

错误后果修正
生产还用默认 JWT_SECRETtoken 安全风险使用强随机密钥
忘记执行 Alembic接口报表不存在上线时跑迁移
CORS 只配 localhost正式域名请求失败配正式域名
只看容器 running实际接口可能 500检查 /health 和关键接口
日志只打到容器里排查困难配日志输出和采集
数据库没挂 volume容器重建数据丢失使用持久化卷和备份

11. 上线检查清单

[ ] .env.prod 已准备且不提交到公开仓库
[ ] JWT_SECRET 是强随机值
[ ] DATABASE_URL 指向正确数据库
[ ] CORS_ORIGINS 包含正式域名
[ ] Alembic migration 已执行
[ ] /health 正常
[ ] Nginx /api 能转发到后端
[ ] HTTPS 正常
[ ] 数据库有持久化和备份方案
[ ] 登录、列表、新增、编辑、删除已验收

12. 总结表

名词大白话
多环境同一套代码用不同配置运行
.env.example配置清单
.env.prod生产钥匙
Docker Compose一张服务启动清单
Nginx入口和反向代理
HTTPS加密访问
健康检查判断服务是否活着
migration数据库结构升级记录
volume容器数据持久化

上一篇建议:大白话讲解——SQLAlchemy 关系查询和性能优化.md

下一篇建议:大白话讲解——AI 应用里的 RAG 知识库实战.md

Checkpoint

读完后做题闯关

先读正文,再用下面的选择题检查自己是否真的理解。答错会出现解释,可以回到正文补一眼再重选。

0/1
先完成阅读

读完正文后点击“我已读完,进入练习”,题目会变成可答状态。

第 1 题

读完这一篇后,最适合怎么确认自己真的理解了?