FastAPI 应用 Docker 容器化指南
容器化 FastAPI 应用:组织项目、编写 Dockerfile、构建运行镜像、查看日志与使用 Docker Compose 开发。生产仍需补充密钥、权限和网络配置。
直接回答:FastAPI + Docker 是 Python API 部署的黄金搭档:Docker 保证环境一致,FastAPI 保证开发效率。一份 Dockerfile、一条 compose 命令,开发到生产同一套环境。
项目结构
fastapi-docker-app/
├── app/
│ ├── __init__.py
│ └── main.py
├── requirements.txt
├── Dockerfile
└── compose.yaml
app/main.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"msg": "FastAPI 容器版上线"}
@app.get("/health")
def health():
return {"status": "ok"}
requirements.txt:fastapi[standard]、uvicorn。
编写 Dockerfile
FROM python:3.13-slim
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
WORKDIR /code
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app ./app
RUN useradd -r app
USER app
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
两个关键习惯:依赖层先于源码层 COPY(构建缓存复用);--host 0.0.0.0 不能少——默认的 127.0.0.1 在容器外不可达,是新手第一大坑。
构建与运行
docker build -t fastapi-app .
docker run -d -p 127.0.0.1:8000:8000 --name api fastapi-app
curl http://localhost:8000/health
容器日志
docker logs api # 查看
docker logs -f api # 跟随
docker logs --since 10m api
应用日志直接 print/logging 到 stdout 即可被 Docker 捕获——不要往容器里写日志文件,容器删了日志就没了。
需要跨容器保留记录时,可按观测云 DataKit 日志采集指南接入 stdout/stderr,给日志设置一致的服务标识,并用一次 /health 请求核对源端与平台记录。
Compose 开发环境
services:
api:
build: .
ports: ["127.0.0.1:8000:8000"]
volumes:
- ./app:/code/app # 代码热挂载
command: uvicorn app.main:app --host 0.0.0.0 --reload
docker compose up 启动,改代码即时重载。生产必须移除 reload 与源码挂载,并配置认证、TLS、健康检查、资源上限、持久化和密钥管理。
常见问题(FAQ)
Q:容器里 --reload 为什么没生效?
A:热重载依赖文件变更事件,若源码只在宿主机改动,需挂载源码;某些虚拟化环境还需启用轮询。生产镜像永远不要带 --reload。
Q:镜像 1GB+ 正常吗?
A:不能只看固定体积区间,机器学习等依赖可能显著增大镜像。检查是否把编译工具链、缓存、测试依赖打进了最终镜像,用多阶段构建瘦身。
Q:容器时区不对怎么办?
A:镜像里 ENV TZ=Asia/Shanghai 并安装 tzdata,或挂载宿主机时区文件。日志时间戳错乱多半是这个问题。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。