应优先使用python:3.9-slim多阶段构建而非alpine,因musl libc导致预编译包缺失、需源码编译失败率高;builder与runner阶段须严格分离,runner中仅复制site-packages和代码,并用--no-cache-dir及显式清理pycache和.pyc。

直接用 python:3.9-slim + 多阶段构建,能砍掉 60% 以上体积;别碰 python:3.9-alpine,它对多数 Python 项目是隐性成本陷阱。
为什么 python:3.9-alpine 容易失败?
Alpine 用 musl libc,而绝大多数预编译的 wheel(如 psycopg2、numpy、cryptography)只提供 glibc 兼容版本。结果就是 pip 强制源码编译——不仅慢,还常报错:
-
fatal error: Python.h: No such file or directory(缺python3-dev或musl-dev) -
ImportError: libpq.so.5: cannot open shared object file(动态链接库找不到) - 构建时间比 slim 版本长 2–3 倍,且失败率陡增
builder 阶段必须装什么、清理什么?
builder 阶段要装编译依赖,但必须在同一条 RUN 中完成安装 + 清理,否则缓存残留会固化进镜像层:
- 只装真正需要的:例如
build-essential、libffi-dev、libssl-dev(不是全量gcc) - 必须加
--no-install-recommends,避免带入非必要包 - 必须连写清理命令:
&& apt-get clean && rm -rf /var/lib/apt/lists/* -
pip install必须带--no-cache-dir,否则/root/.cache/pip会悄悄占掉 100MB+
runner 阶段复制哪些路径才安全?
runner 阶段的目标是“零编译工具、零缓存、零源码”,只保留运行时绝对必需的东西:
- 不要
COPY --from=builder /usr/local—— 这会把/usr/local/bin/gcc等二进制一起拖进来 - 推荐做法:在 builder 中用
pip install --user,然后只复制/root/.local;或用 venv 后只复制/opt/venv/lib/python3.9/site-packages和/opt/venv/bin下的可执行文件 - 务必跳过
__pycache__和*.pyc:find /opt/venv -name "*.pyc" -delete - runner 阶段禁止再执行任何
RUN pip install,那会让所有依赖重新进一层
最容易被忽略的是:多阶段不是靠写两个 FROM 就算数,而是看最终镜像里有没有 gcc、apt、.cache 这些东西——用 docker run --rm -it your-image ls /usr/bin | grep gcc 实测最靠谱。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











