必须使用 docker buildx build,因其支持多平台构建和镜像裁剪;需先创建并验证 builder 实例,显式指定 --platform,选用 python:3.12-slim-bookworm 基础镜像,分层安装依赖,删除无用 -nspkg.pth 文件。

用 docker buildx build 替代 docker build 是必须的
普通 docker build 默认不支持多平台构建,也压根不会帮你裁剪 Python 运行时。想得到轻量镜像,第一步就得切到 buildx —— 它是唯一能真正控制基础镜像、编译目标和层优化的入口。
常见错误是本地没启用 buildx builder 实例,直接跑命令报错:error: no builder found。得先执行:
docker buildx create --use --name mybuilder --bootstrap再验证:
docker buildx inspect --bootstrap看到
linux/amd64 和 linux/arm64 都 ready 才算过关。
- 别用
DOCKER_BUILDKIT=1 docker build试图“凑合”,它不解决平台适配和二进制精简问题 - 如果 CI 环境没装 QEMU(比如 GitHub Actions 默认没开),
buildx会静默 fallback 到本地架构,结果镜像跑不到 ARM 机器上 -
--platform linux/amd64,linux/arm64要显式写,别依赖默认值
选对基础镜像:优先用 python:3.12-slim-bookworm,别碰 alpine
slim-bookworm 是目前最平衡的选择:比 full 小 60%,自带 glibc 和常用编译工具链,绝大多数纯 Python 包(包括带 C 扩展的 numpy、psycopg2)能直接 pip install 成功;而 alpine 表面更小,但常因 musl 兼容性翻车,比如 tensorflow 或某些二进制 wheel 根本装不上。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 确认项目没硬依赖
glibc > 2.36(Bookworm 自带 2.36),否则要换python:3.12-slim-bullseye - 避免用
python:3.12-slim这种不带发行版后缀的 tag——Docker Hub 上它可能指向旧版,行为不可控 - 如果真要用 alpine,必须加
RUN apk add --no-cache gcc musl-dev linux-headers,体积反而接近 slim
pip install --no-cache-dir --no-deps 不是银弹,得配合 requirements.txt 分层
盲目加 --no-cache-dir 只是减少构建中间层体积,对最终镜像大小几乎没影响;真正起效的是把依赖分三类写进不同 RUN 指令:不变的系统级依赖(如 setuptools)、变动少的三方包(requests, pydantic)、高频变更的应用代码。这样 Docker 缓存才真正生效。
示例结构:
RUN pip install --no-cache-dir setuptools wheel<br>RUN pip install --no-cache-dir -r requirements-base.txt<br>COPY . /app<br>RUN pip install --no-cache-dir -e .
-
requirements-base.txt里只放稳定大包,每次改它都会失效缓存,所以得定期 pin 版本,别用~>或>= - 别在
COPY . /app后立刻pip install -r requirements.txt——哪怕只改一行代码,整个依赖层全重装 -
--no-deps仅适用于你明确知道依赖已满足的场景(如只装一个 wheel 文件),误用会导致运行时报ImportError
删掉 /usr/local/lib/python*/site-packages/*-nspkg.pth 这类无用文件
某些包(尤其是老版本 setuptools 或 pkg-resources)会在 site-packages 下生成几十 KB 的 -nspkg.pth 文件,它们既不被加载,也不参与 import,纯属历史残留。在最终镜像里删掉它们,每镜像能省 1–3MB,积少成多。
操作很简单,在最后一步加:
RUN find /usr/local/lib/python*/site-packages/ -name "*-nspkg.pth" -delete
- 别用
rm -rf /usr/local/lib/python*/site-packages/*-nspkg.pth——find -delete更安全,不会因 glob 展开失败而误删 - 这个动作必须放在所有
pip install之后、COPY应用代码之前,否则新装包可能又带进来 - 如果用了
pip-tools生成requirements.txt,检查是否含pkg-resources—— 它是典型元凶,应从requirements.in中排除
轻量镜像不是靠单点技巧堆出来的,而是每一层都得问一句:这东西运行时真需要吗?PATH 里有没有冗余路径?/tmp 下有没有残留编译产物?漏掉任意一环,前面所有优化都白搭。










