知其然,知其所以然
Docker 容器原理 2026-10-10

构建上下文:docker build 到底把哪些文件发给了守护进程

在 Docker Engine 29.8.2(BuildKit)里实测构建上下文:目录里有 50 MiB 的无关文件,Dockerfile 只 COPY 一个小文件时只传输 40 B(564 ms),COPY . 时传输 52.44 MB(1923 ms);再构建一次传输只有 137 B 且命中缓存;改一个小文件只传 155 B;没有上下文或想 COPY 上下文之外的文件都会 not found。

Docker 构建上下文 BuildKit docker build COPY 真实验证 动画演示
Docker 容器原理 2026-10-10

.dockerignore:忽略规则怎么影响上下文大小和缓存

在 Docker Engine 29.8.2(BuildKit)里实测 .dockerignore:30 MiB 的 node_modules 不忽略时传输 31.47 MB,忽略后只传 509 B(285 ms 对 1625 ms);`*.log` 只管根目录、`/build` 只匹配根目录的 build、`**/` 才匹配任意深度、`!` 例外规则后者覆盖前者;忽略经常变化的文件让 COPY 层保持缓存;Dockerfile.dockerignore 取代 .dockerignore。

Docker dockerignore 构建上下文 构建缓存 BuildKit 真实验证 动画演示
Docker 容器原理 2026-10-10

删除文件为什么不减小镜像:whiteout 文件与层

在 Docker Engine 29.8.2 里实测“删除文件不会减小镜像”:先 dd 20 MiB 再下一个 RUN 里 rm,镜像比 alpine 多 41.96 MB(Size 把压缩内容和解包层各算一次),而同一个 RUN 里 dd && rm 多 0.00 MB;docker save 的层 tar 里,删除那一层只有一个 0 字节的 .wh.big.bin;从 gen 阶段启动能看到文件,最终镜像看不到;多阶段构建后只多 0.01 MB。

Docker 镜像层 whiteout 多阶段构建 docker save 真实验证 动画演示
Docker 容器原理 2026-10-10

COPY 与 ADD:自动解压和远程 URL 的差别

在 Docker Engine 29.8.2(BuildKit)里实测 COPY 与 ADD:ADD 会自动解压本地的 tar 和 tar.gz,但不解压 zip,COPY 从不解压;ADD 目录与 COPY 目录结果相同;ADD 远程 URL 下载的文件权限是 0600 属主 root,压缩包不会被解压;ADD --checksum 摘要不对时构建失败。

Docker COPY ADD Dockerfile 自动解压 真实验证 动画演示
Docker 容器原理 2026-10-10

ENTRYPOINT 与 CMD:两者组合后的最终命令

在 Docker Engine 29.8.2 里实测 ENTRYPOINT 与 CMD 的 9 种组合(用 docker create + inspect 的 Path/Args 看最终命令):docker run 后的参数只替换 CMD;--entrypoint 覆盖入口;shell 形式的 ENTRYPOINT 会让 CMD 变成 sh -c 的位置参数而被脚本忽略;exec 形式入口 + shell 形式 CMD 时入口收到 /bin/sh -c …;以及 PID 1 在 exec 形式、单条 shell 命令、复合 shell 命令下各是谁。

Docker ENTRYPOINT CMD exec形式 shell形式 真实验证 动画演示
Docker 容器原理 2026-10-10

exec 与 shell 形式:PID 1 与信号能不能传到你的程序

在 Docker Engine 29.8.2 里实测信号能不能传到你的程序:exec 形式、单条 shell 命令和 exec 接管都能在 0.1 秒内收到 SIGTERM 并退出(退出码 0);复合 shell 命令让 PID 1 变成 sh,docker stop 等满超时 3.13 秒后以 137 结束;没有信号处理的程序当 PID 1 会忽略 SIGTERM(3.16 秒,137),加 --init 后 0.13 秒、退出码 143。

Docker PID 1 信号 exec形式 shell形式 docker stop 真实验证 动画演示
Docker 容器原理 2026-10-10

ARG 与 ENV:构建参数在镜像里留下了什么痕迹

在 Docker Engine 29.8.2 里实测 ARG 与 ENV 留下的痕迹:ARG 运行时不存在,但 --build-arg 的明文值写进了 docker history(3 行)和镜像配置(docker save 的 tar 里 1 个文件含它),BuildKit 对敏感 ARG 给出警告;改任何一个 ARG 都会让它之后所有 RUN 的缓存失效;FROM 之前的 ARG 进入阶段后要重新声明才能用;ENV 可在运行时用 -e 覆盖。

Docker ARG ENV 构建参数 密钥泄漏 构建缓存 真实验证 动画演示
Docker 容器原理 2026-10-10

构建期密钥:--mount=type=secret 与直接 COPY 的区别

在 Docker Engine 29.8.2 里实测构建期密钥:COPY 再 rm 的密钥仍留在较早的层里,--build-arg 的密钥写进镜像配置和 docker history,而 RUN --mount=type=secret 在所有层和配置里都找不到密钥,运行时也没有 /run/secrets;支持 env= 传入;密钥内容不参与缓存键(换密钥仍 CACHED);required=true 缺密钥时构建失败;命令把密钥 cp 到别处仍会写进镜像。

Docker 构建密钥 BuildKit secret mount 镜像泄漏 真实验证 动画演示
Docker 容器原理 2026-10-10

BuildKit 缓存挂载:包管理器缓存怎么跨构建复用

在 Docker Engine 29.8.2(BuildKit)里实测缓存挂载:apk add curl 不带缓存挂载时每次构建 98–196 秒(这台机器网络很慢),带 RUN --mount=type=cache 后第一次要 193.7 秒,之后每次只要 0.76–0.94 秒;缓存里的 13 个文件(4644 KB)不进镜像;不同 id 是互相独立的缓存。

Docker BuildKit 缓存挂载 构建缓存 apk 真实验证 动画演示
Docker 容器原理 2026-10-10

BuildKit 并行构建:多阶段里互不依赖的阶段怎么并发

在 Docker Engine 29.8.2(BuildKit)里实测多阶段构建的并发:两个各睡 4 秒的独立阶段总共 4.34 秒(串行至少 8 秒),有依赖的阶段 8.53 秒,同一阶段内两条 RUN 8.51 秒;最终镜像用不到的阶段不会被执行(0.33 秒),--target 它才执行(3.33 秒);4 个独立阶段 4.45 秒。

Docker BuildKit 多阶段构建 并行构建 构建速度 真实验证 动画演示
Docker 容器原理 2026-10-10

buildx 多平台镜像:manifest list 里放了什么

在 Docker Engine 29.8.2(containerd 镜像存储)里实测 buildx 多平台镜像:--platform linux/amd64,linux/arm64 可以 --load;镜像索引(OCI index)里有 4 个 manifest——amd64 和 arm64 各一个(480 字节),外加两个 unknown/unknown 的 attestation manifest(835 字节);arm64 的 Docker Desktop 上 amd64 镜像也能跑,3 亿次整数循环 496 ms 对原生 366 ms。

Docker buildx 多平台镜像 manifest list OCI index 真实验证 动画演示
Docker 容器原理 2026-10-10

基础镜像对比:alpine、debian-slim 与 distroless 的真实体积

在 Docker Engine 29.8.2(linux/arm64)里实测基础镜像体积:busybox 6.14MB、alpine 13.6MB、debian:12-slim 136MB、ubuntu:24.04 139MB;同一个 1.57 MB 的静态 Go 程序放进 scratch / busybox / alpine / debian-slim / ubuntu,镜像分别是 2.22 / 8.36 / 15.80 / 138.15 / 141.60 MB;scratch 里没有 sh。

Docker 基础镜像 alpine debian-slim scratch 镜像体积 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号