用 python:3.9-slim 是因它基于 debian slim,仅含运行时必需组件(约120mb),大幅减少攻击面、缓存污染和误用 dev 工具风险;但缺编译能力,需多阶段构建配合 wheel 预编译及严格清理 apt/pip 缓存与 pycache。

为什么用 python:3.9-slim 而不是 python:3.9
标准 python:3.9 镜像基于完整 Debian,自带大量开发工具(gcc、make、curl 等)和调试依赖,体积常超 900MB;python:3.9-slim 基于 Debian slim 版本,只保留运行时必需的库和二进制,基础镜像约 120MB。关键不是“小”,而是“没多余东西”——少了攻击面、少了缓存污染风险、少了构建时误用 dev 工具的可能。
注意:-slim 镜像不带 pip 的编译能力(缺 build-essential),如果项目有 cffi、pydantic(含 rust 绑定)、或任何需要 setup.py 编译的包,直接 pip install 会失败。
多阶段构建中如何安全安装编译型依赖
不能在最终镜像里装 build-essential,但又得编译 —— 多阶段构建是唯一稳妥解法。第一阶段用完整镜像编译,第二阶段只拷二进制/已编译的 site-packages。
- 第一阶段用
python:3.9或python:3.9-bullseye,RUN pip wheel --no-deps --wheel-dir /wheels -r requirements.txt - 第二阶段用
python:3.9-slim,COPY --from=0 /wheels /wheels,再RUN pip install --no-index --find-links /wheels --trusted-host None *.whl - 避免用
pip install -r requirements.txt直接在 slim 镜像里跑,尤其当requirements.txt含psycopg2、numpy、cryptography时,大概率卡在gcc找不到
apt-get clean 和 rm -rf /var/lib/apt/lists/* 必须成对出现
在 slim 镜像里如果要用 apt-get 装系统级依赖(比如 libpq-dev 用于 psycopg2 构建,或 libglib2.0-0 用于某些图像库),装完不清理,缓存会留在镜像层里,体积不降反升。
正确写法是:
RUN apt-get update \ && apt-get install -y libpq5 \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean
单独执行 apt-get clean 不够:它只清 /var/cache/apt/archives/,而 /var/lib/apt/lists/(下载的包索引)占空间更大,且不会被 clean 清掉。漏掉任一环节,镜像体积可能多出 40–60MB。
Python 缓存和临时文件必须显式删除
pip 默认会在安装时留下 __pycache__、.pyc、pip 缓存目录、甚至未完成的 wheel 构建中间件。这些全在镜像层里,且不会自动清理。
-
RUN pip install --no-cache-dir -r requirements.txt:禁用 pip 缓存,省下 ~100MB -
RUN find /usr/local -name __pycache__ -type d -exec rm -rf {} + 2>/dev/null || true:递归删 pycache(路径取决于 Python 安装位置) - 如果用了
pip wheel,确保/wheels目录在最终镜像里不存在,否则白占空间
容易被忽略的是:Docker 构建过程中,哪怕某一层 RUN rm -rf /tmp/*,只要上一层留了东西,它依然在镜像里 —— 所以清理动作必须和安装动作放在同一层,否则无效。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











