多阶段构建通过分离构建与运行阶段天然实现清理,关键在于用至少两个from指令、copy --from精准复制、运行阶段显式清除缓存及构建后执行docker builder prune。

多阶段构建本身不是清理命令,而是通过“只复制必要产物、丢弃整个构建阶段”的设计,天然实现中间产物的隔离与剔除。关键不在于“怎么清理”,而在于“怎么写才能确保不留残留”。
明确分离构建与运行阶段
必须使用至少两个 FROM 指令,且第二阶段不能继承第一阶段的文件系统。Docker 构建引擎会在最终镜像中完全忽略构建阶段的层,包括编译器、源码、临时文件、缓存包目录(如 /var/cache/apk 或 ~/.cache/pip)等。
- 构建阶段用完整镜像(如
python:3.11-slim或golang:1.22),专注编译/安装 - 运行阶段用最小镜像(如
alpine:3.20或scratch),只接收二进制或已打包依赖 - 禁止在运行阶段重复
RUN apt-get install或pip install—— 这会让依赖重新下载并残留缓存
精准复制,避免隐式带入
COPY --from=builder 是唯一可控的产物传递方式。它只拷贝指定路径内容,不会带入构建阶段的环境变量、用户配置或系统目录。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 不要写
COPY --from=builder / /—— 这会意外复制整个根文件系统 - 推荐显式路径:比如
COPY --from=builder /app/dist/*.js /usr/share/nginx/html/ - 对 Python 应用,优先复制
/root/.local而非整个/usr/local,避免混入构建时的 pip 缓存或 .egg-info
运行阶段主动清理不可见残留
即使用了 Alpine,某些包管理器(如 apk)默认会保留索引和缓存。需在运行阶段显式清除:
- Alpine 中用
apk --no-cache add xxx,而非apk add xxx - 若需手动清理,加一句
RUN rm -rf /var/cache/apk/*(放在apk add后立即执行) - 对 Node.js,避免
npm install后不删node_modules/.cache;建议用--no-cache或构建后RUN npm ci --only=production
构建完成后手动清理未引用缓存
多阶段构建虽不把中间层打入最终镜像,但构建缓存仍保留在本地。这些缓存不会自动删除,长期积累占用磁盘。
- 每次构建后执行:
docker builder prune(清理未被任何镜像引用的构建缓存) - CI 环境建议加到流水线末尾,防止缓存膨胀
- 若想彻底重置,可用
docker builder prune -a,但下次构建会变慢










