使用Docker构建Python FastAPI镜像的最佳实践
作者:展菲
前言
用 Docker 部署 Python FastAPI 应用时,镜像过大会拖慢拉取和部署,依赖或权限不当又容易带来安全与可维护性问题。通过多阶段构建、精简基础镜像、非 root 运行等方式,可以在保证功能的前提下减小体积并提升安全性。
本文只讲 Dockerfile 的关键写法和注意点,不贴完整可运行项目。
基础 Dockerfile 示例
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
要点:
- python:3.11-slim:相比默认
python:3.11体积小很多,一般已够用;若依赖 C 库,再考虑slim或alpine的取舍。 - WORKDIR /app:后续 COPY、RUN 都在此目录,便于路径统一。
- 先 COPY requirements.txt 再 COPY .:利用层缓存,依赖不变时不会重复
pip install。 - –no-cache-dir:不保留 pip 缓存,减小镜像体积。
- CMD 用数组形式:避免通过 shell 解析,信号能正确传到 uvicorn。
多阶段构建减小体积
若构建阶段需要编译或额外工具,可用多阶段:第一阶段装依赖、编译,第二阶段只保留运行时需要的文件。
# 构建阶段(可选:需要编译时用) FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --user -r requirements.txt # 运行阶段 FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local ENV PATH=/root/.local/bin:$PATH COPY . . EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
这里把 pip install --user 的结果从 builder 拷到最终镜像,避免把构建工具、临时文件带进去。若依赖全是 wheel,也可以不用 builder,只在最终阶段装依赖。
.dockerignore 减少上下文与层
在项目根目录建 .dockerignore,避免把无关文件打进镜像、拉长构建时间:
__pycache__ *.pyc .git .venv venv .env *.md tests .pytest_cache .coverage htmlcov
这样 COPY . . 不会包含上述内容,镜像更干净,构建更快。
非 root 运行(可选但推荐)
在 Dockerfile 中新建用户并用该用户运行进程,降低容器内权限风险:
FROM python:3.11-slim RUN groupadd -r app && useradd -r -g app app WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY --chown=app:app . . USER app EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
注意:若应用要写当前目录(如日志、上传),需保证 WORKDIR 对 app 可写;挂载卷时也要注意宿主目录权限。
环境变量与配置
敏感信息(如 DB 地址、密钥)不要写进镜像,运行时通过环境变量或挂载注入:
ENV PYTHONUNBUFFERED=1 # 不在这里写 DATABASE_URL、SECRET_KEY 等
在 docker run 或 docker-compose.yml 中传:
environment: - DATABASE_URL=postgresql://... - SECRET_KEY=...
应用内用 os.getenv('DATABASE_URL') 或 pydantic Settings 读取即可。
健康检查
在 Dockerfile 或 compose 中加健康检查,便于编排系统判断容器是否就绪:
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health')" || exit 1
前提是应用提供 /health 等轻量接口;若没有,可先用 curl 或 wget 测根路径,或暂时去掉 HEALTHCHECK。
总结
- 基础镜像选
slim,先 COPY requirements 再 COPY 代码,用--no-cache-dir,CMD 用数组。 - 需要时用多阶段构建和
.dockerignore减小体积、加快构建。 - 推荐非 root 用户运行,敏感配置用环境变量注入,按需加 HEALTHCHECK。
按上述方式构建的 FastAPI 镜像更小、更安全、更利于 CI/CD 与生产部署。
到此这篇关于使用Docker构建Python FastAPI镜像的最佳实践的文章就介绍到这了,更多相关Docker构建Python FastAPI镜像内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
