FastAPI Docker 部署最佳实践

FastAPI 生产容器化的七条实践:扎实的 Dockerfile、环境配置、健康检查、层缓存优化、数据库连接与迁移、日志配置与水平扩展准备。

最佳实践
容器模块与编排港口插画

直接回答:FastAPI 从玩具到生产,Docker 部署要过七关:多阶段精简镜像、配置外置、健康检查、构建缓存优化、数据库连接管理、结构化日志与无状态扩展准备——每一条都是扛住真实流量的必修课。

1. 打好 Dockerfile 地基

FROM python:3.13-slim AS base
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
WORKDIR /app

FROM base AS deps
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

FROM base
COPY --from=deps /install /usr/local
COPY . .
RUN useradd -r app && chown -R app /app
USER app

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

slim 基础镜像、多阶段构建、非 root 运行——地基三件套一次到位。

2. 配置全部外置

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    database_url: str
    secret_key: str
    debug: bool = False

    model_config = SettingsConfigDict(env_file=".env")

settings = Settings()

镜像里零密钥,dev/staging/prod 共用一份镜像。Pydantic Settings 顺带把类型校验也做了。

3. 健康检查

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

@app.get("/health/ready")
def ready():
    # 局部片段:engine 为项目的 SQLAlchemy Engine
    with engine.connect() as conn:
        conn.execute(text("SELECT 1"))  # 需 from sqlalchemy import text
    return {"status": "ready"}

liveness 探活、readiness 探可服务——编排系统据此决定重启与摘流量,滚动发布不断线就靠这对组合。

4. 吃透层缓存

requirements.txt 先于源码 COPY:依赖不变时构建秒完。.dockerignore 排除 .git、__pycache__、测试目录、.env 和私钥,上下文小了传输也快。CI 里开 BuildKit 缓存挂载,已有缓存可减少重复下载,首次冷构建不保证提速。

5. 数据库连接与迁移

  • 连接池:create_engine(url, pool_size=10, max_overflow=20),池子别超过数据库承受力;
  • 迁移:Alembic 迁移作为发布流水线的独立步骤(独立 K8s Job,避免每个 Pod 的 init 容器并发迁移),绝不由每个副本启动时抢跑;
  • 启动重试:数据库未就绪时采用有上限的退避重试或由编排器重启,并保持 readiness 失败。

6. 日志配置

容器里常用的日志方式:结构化 JSON 写 stdout。

import logging, json, sys

handler = logging.StreamHandler(sys.stdout)
from pythonjsonlogger.json import JsonFormatter  # 需安装 python-json-logger
handler.setFormatter(JsonFormatter())
logging.basicConfig(level="INFO", handlers=[handler])

uvicorn 的访问日志同样引到 stdout。用 DataKit 容器日志采集接入观测云时,先触发一次接口错误,核对应用日志与访问日志的时间、服务名和请求标识,确认没有重复采集。

7. 为水平扩展做准备

FastAPI 应用天然易扩——前提是保持无状态:

  • 会话与缓存放 Redis,不放进程内存;
  • 文件上传走对象存储,不落本地盘;
  • 后台重任务丢任务队列,不卡 worker;
  • --workers 数按 CPU 核数定,多副本优先于单副本多 worker(滚动更新更平滑)。

常见问题(FAQ)

Q:Uvicorn 还要不要前面架 Nginx?
A:容器编排环境下,Ingress/网关已承担 TLS 与路由,Uvicorn 直连通常足够;裸机部署则建议加一层 Nginx/Caddy 做 TLS 与限流。

Q:Gunicorn+Uvicorn worker 还是纯 Uvicorn 多进程?
A:两者都行。K8s 时代更推荐纯 Uvicorn 单进程 + 多副本,生命周期由编排系统统一管理。

Q:镜像里要装 curl 吗(健康检查用)?
A:尽量不装——slim 镜像里用 Python 一行或编排系统的 HTTP 探针即可。每多一个包都是攻击面。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台