服务部署
前言
FastAPI 应用本身只是一个 ASGI 应用,需要由 ASGI 服务器(如 Uvicorn)承载运行。本章整理生产环境部署的常用方案与最佳实践。
生产环境配置
上线前先做几件事(详见各章节):
- 关闭 OpenAPI 文档或加访问控制(读取应用配置)。
- 配置
TrustedHostMiddleware、CORS 白名单(中间件)。 - 配置日志与链路追踪(补充:TrackingID 的设计)。
- 使用环境变量/配置中心管理密钥(读取应用配置)。
Uvicorn 单进程
最简单的方式,适合内部服务或低并发场景:
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 2
--workers指定工作进程数,一般取 CPU 核数(或2 * CPU核数 + 1,参考 gunicorn 建议)。- 多进程时注意:内存态数据、后台定时任务互不共享,需要外部协调(见 补充:基于 DB 的分布式锁)。
- 生产环境不要开启
--reload。
Gunicorn + Uvicorn Workers(推荐)
Gunicorn 是进程管理器,搭配 Uvicorn worker 可以让多进程 + 优雅重启更可靠:
python -m pip install gunicorn uvicorn
# -w 工作进程数,-k uvicorn.workers.UvicornWorker 使用异步 worker
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
优点:
- 进程级管理(worker 崩溃自动重启、优雅退出)。
- 支持
--timeout、--graceful-timeout等生产参数。 - 如果使用
UvicornWorker,也可以配合--max-requests定期回收 worker 防止内存泄漏。
备注
如果代码里有同步阻塞的第三方库(如部分 ORM 同步驱动),可以使用 uvicorn.workers.UvicornH11Worker,或者考虑用 --threads 增加每进程线程数。纯异步代码用默认 UvicornWorker 即可。
Systemd 管理
# /etc/systemd/system/fastapi.service
[Unit]
Description=FastAPI application
After=network.target
[Service]
User=www-data
WorkingDirectory=/srv/myapp
EnvironmentFile=/srv/myapp/.env
ExecStart=/srv/myapp/.venv/bin/gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 127.0.0.1:8000
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now fastapi
Docker 部署
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:8000"]
docker build -t myapp .
docker run -d --name myapp -p 8000:8000 --env-file .env myapp
在 k8s 中部署时,建议配置 liveness/readiness 探针(如指向 /healthz 接口)、资源限制与 HPA。
Nginx 反向代理
FastAPI 应用监听内网端口,由 Nginx 对外提供 HTTPS 与反向代理:
server {
listen 80;
server_name api.example.com;
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;
}
# WebSocket 需要显式配置升级头
location /ws {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
注意
走反向代理后,request.client.host 拿到的是代理地址,需要通过 X-Forwarded-For 获取真实 IP(或配置 ProxyHeadersMiddleware / Uvicorn 的 --proxy-headers);HTTPS 由 Nginx 终结时,应用内判断协议也要依赖 X-Forwarded-Proto。