12.1 生产配置:DEBUG=False, SECRET_KEY 安全管理
在开发阶段,FastAPI 默认开启调试模式(debug=True),这会暴露详细的错误信息,方便开发者排查问题。但在生产环境中,必须关闭调试模式,防止敏感信息泄露。
同时,SECRET_KEY 是用于 JWT 签名、会话加密等安全功能的核心密钥,绝不能硬编码在代码中,更不能提交到版本控制系统(如 Git)。
核心做法:
- 使用
.env文件存储敏感配置 - 通过 Pydantic
BaseSettings自动加载环境变量 - 在生产部署时通过环境变量覆盖
.env中的值
下面是一个安全的配置管理示例:
# app/core/config.py
from pydantic_settings import BaseSettings # 注意:Pydantic v2 中是 pydantic_settings
class Settings(BaseSettings):
# 应用基础配置
APP_NAME: str = "My FastAPI App"
DEBUG: bool = False # 生产环境必须为 False
# 安全密钥(从环境变量读取,若无则报错)
SECRET_KEY: str
# 数据库连接
DATABASE_URL: str
# Redis 配置
REDIS_HOST: str = "localhost"
REDIS_PORT: int = 6379
class Config:
env_file = ".env" # 指定 .env 文件路径
env_file_encoding = "utf-8"
# 创建全局配置实例
settings = Settings()对应的 .env 文件(不要提交到 Git):
DEBUG=False
SECRET_KEY=your_very_long_random_secret_key_here_123!@#
DATABASE_URL=mysql+asyncmy://user:password@localhost/dbname
REDIS_HOST=redis小提示:生成强 SECRET_KEY 可以用 Python 命令:
python -c "import secrets; print(secrets.token_urlsafe(32))"
这一节讲了如何在生产环境中安全地管理配置,特别是关闭调试模式和保护 SECRET_KEY,这是保障应用安全的第一道防线。
12.2 Docker 化:多阶段构建镜像(包含 MySQL + Redis)
为了确保开发、测试、生产环境一致,我们使用 Docker 容器化部署。采用 多阶段构建 可以减小最终镜像体积,提升安全性。
项目根目录创建 Dockerfile:
# 第一阶段:构建依赖
FROM python:3.10-slim AS builder
# 设置工作目录
WORKDIR /app
# 安装系统依赖(可选)
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖到虚拟环境(减小体积)
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
# 第二阶段:运行时镜像
FROM python:3.10-slim
# 创建非 root 用户(安全最佳实践)
RUN useradd --create-home --shell /bin/bash app
USER app
WORKDIR /home/app
# 从 builder 阶段复制虚拟环境
COPY --from=builder --chown=app:app /opt/venv /opt/venv
# 复制应用代码
COPY --chown=app:app . .
# 激活虚拟环境
ENV PATH="/opt/venv/bin:$PATH"
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]同时,使用 docker-compose.yml 编排整个服务(含 MySQL 和 Redis):
# docker-compose.yml
version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
web:
build: .
depends_on:
- db
- redis
environment:
- DATABASE_URL=mysql+asyncmy://appuser:apppass@db/myapp
- REDIS_HOST=redis
- SECRET_KEY=production_secret_key_change_me
- DEBUG=False
ports:
- "8000:8000"
volumes:
- ./app:/home/app/app # 开发时可挂载,生产建议移除
volumes:
mysql_data:这一节展示了如何通过 Docker 多阶段构建优化镜像,并用 docker-compose 统一管理 FastAPI、MySQL 和 Redis 三个服务,实现“一次构建,随处运行”。
12.3 进程管理:Uvicorn + Gunicorn(多 worker)
虽然 Uvicorn 本身支持异步高并发,但在生产环境中,通常将其作为 ASGI 工作进程,由 Gunicorn 作为进程管理器来启动多个 Uvicorn worker,以充分利用多核 CPU。
首先安装 Gunicorn 和 Uvicorn 的 Gunicorn worker:
pip install gunicorn uvicorn[standard]然后创建 Gunicorn 配置文件 gunicorn_conf.py:
# gunicorn_conf.py
import multiprocessing
# 绑定地址
bind = "0.0.0.0:8000"
# 工作进程数:通常为 CPU 核心数 + 1
workers = multiprocessing.cpu_count() + 1
# 每个 worker 使用 Uvicorn 的 ASGI 工作类
worker_class = "uvicorn.workers.UvicornWorker"
# 最大请求处理数后重启 worker(防内存泄漏)
max_requests = 1000
max_requests_jitter = 100
# 超时设置(秒)
timeout = 60
# 日志级别
loglevel = "info"修改 Dockerfile 的启动命令:
# 替换原来的 CMD
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "app.main:app", "-c", "gunicorn_conf.py"]或者在 docker-compose.yml 中指定:
# 在 web 服务下
command: gunicorn -k uvicorn.workers.UvicornWorker app.main:app -c gunicorn_conf.py注意:由于 FastAPI 是纯异步应用,每个 Uvicorn worker 本身就能处理大量并发连接。增加 worker 数量主要是为了利用多核并行处理 CPU 密集型任务或提高容错性。
这一节介绍了如何用 Gunicorn 管理多个 Uvicorn worker,提升应用的吞吐量和稳定性,是生产部署的标准做法。
12.4 Nginx 反向代理:静态文件 + HTTPS 配置
Nginx 作为反向代理,可以:
- 处理 HTTPS(SSL/TLS 终止)
- 提供静态文件服务(如前端资源)
- 负载均衡(多实例)
- 缓存、限流等高级功能
首先,在项目中创建 nginx.conf:
# nginx.conf
upstream fastapi_app {
server web:8000; # docker-compose 中的服务名
}
server {
listen 80;
server_name your-domain.com;
# 强制跳转 HTTPS(生产环境推荐)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL 证书(需提前申请,如 Let's Encrypt)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# 安全头
add_header Strict-Transport-Security "max-age=31536000" always;
# API 路由代理到 FastAPI
location / {
proxy_pass http://fastapi_app;
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;
}
# 静态文件(如 Swagger UI、前端打包文件)
location /static/ {
alias /var/www/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}更新 docker-compose.yml 加入 Nginx 服务:
services:
# ... 其他服务
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./ssl:/etc/nginx/ssl # 存放证书
- ./static:/var/www/static # 静态文件目录
depends_on:
- webHTTPS 小贴士:可使用 Certbot 自动申请 Let's Encrypt 免费证书,或在云服务商(如阿里云、腾讯云)控制台一键部署。
这一节讲解了如何用 Nginx 作为反向代理,处理 HTTPS 和静态文件,让 FastAPI 专注于业务逻辑,提升整体架构的安全性和性能。