Docker入门:镜像层与Dockerfile疑问及history解析
docker history的疑问解答 运行环境
docker --version Docker version 24.0.7, build afdd53b wsl --version WSL version: 2.0.14.0 Kernel version: 5.15.133.1-1 WSLg version: 1.0.59 MSRDC version: 1.2.4677 Direct3D version: 1.611.1-81528511 DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp Windows version: 10.0.19045.3803
使用的Dockerfile
FROM node:18-alpine WORKDIR /app COPY . . RUN yarn install --production CMD ["node", "src/index.js"] EXPOSE 3000
docker history输出
docker history f2b23ca3d96bcf2b300cb43626072454c87f4284a028860c4703b0354dee7fe5 IMAGE CREATED CREATED BY SIZE COMMENT f2b23ca3d96b 4 days ago EXPOSE map[3000/tcp:{}] 0B buildkit.dockerfile.v0 <missing> 4 days ago CMD ["node" "src/index.js"] 0B buildkit.dockerfile.v0 <missing> 4 days ago RUN /bin/sh -c yarn install --production # b… 85.3MB buildkit.dockerfile.v0 <missing> 4 days ago COPY . . # buildkit 6.49MB buildkit.dockerfile.v0 <missing> 5 days ago WORKDIR /app 0B buildkit.dockerfile.v0 <missing> 6 days ago /bin/sh -c #(nop) CMD ["node"] 0B <missing> 6 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B <missing> 6 days ago /bin/sh -c #(nop) COPY file:4d192565a7220e13… 388B <missing> 6 days ago /bin/sh -c apk add --no-cache --virtual .bui… 7.77MB <missing> 6 days ago /bin/sh -c #(nop) ENV YARN_VERSION=1.22.19 0B <missing> 6 days ago /bin/sh -c addgroup -g 1000 node && addu… 117MB <missing> 6 days ago /bin/sh -c #(nop) ENV NODE_VERSION=18.19.0 0B <missing> 10 days ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 10 days ago /bin/sh -c #(nop) ADD file:1f4eb46669b5b6275… 7.38MB
疑问解答
为何存在多个CMD?Docker文档明确说明仅最后一个CMD生效。
多个CMD来自镜像的继承链:最底层的CMD ["/bin/sh"]是alpine基础镜像的默认命令,中间的CMD ["node"]是node:18-alpine镜像设置的,你编写的CMD ["node", "src/index.js"]是顶层指令。运行容器时只有最后一个CMD会生效,前面的CMD只是镜像构建过程中的历史记录,不影响最终容器启动行为。如何查看完整的层条目内容?Docker Desktop和命令行均未完整显示。
命令行执行docker history --no-trunc <镜像ID>,添加--no-trunc参数后,就能看到未被截断的完整CREATED BY内容。docker history输出中的<missing>是什么?为何这些层的创建日期差异大?<missing>表示这些层是从镜像仓库拉取的基础镜像层,本地仅保存自己构建的顶层镜像ID,基础镜像的层ID不会在本地完整记录,因此显示<missing>。- 创建日期差异是因为各层属于不同的镜像阶段:最底层的alpine基础镜像层10天前构建,node镜像基于alpine,它的层6天前构建,你本地构建的层是4-5天前生成的,每个镜像的更新时间不同,导致日期有差异。
部分层中添加的
# buildkit标识是什么?Dockerfile中无对应内容。# buildkit是Docker BuildKit构建引擎自动添加的标记。当使用BuildKit(默认启用)构建镜像时,它会在构建指令后添加该注释,用于标识层由BuildKit处理生成,和你编写的Dockerfile内容无关。Docker Desktop层视图中部分箭头灰色、部分正常,是否与层来源有关?
是的。灰色箭头对应从仓库拉取的基础镜像层(即docker history中显示<missing>的层),正常颜色箭头对应你本地Dockerfile构建生成的层。灰色表示这些层是共享的基础层,无需本地重新构建。
docker history条目逐行解释
按从上到下的顺序(顶层到底层):
f2b23ca3d96b 4 days ago EXPOSE map[3000/tcp:{}] 0B buildkit.dockerfile.v0
你Dockerfile中EXPOSE 3000指令生成的元数据层,仅声明容器暴露3000端口,不做实际端口映射,因此大小为0B。<missing> 4 days ago CMD ["node" "src/index.js"] 0B buildkit.dockerfile.v0
你Dockerfile中CMD指令生成的元数据层,定义容器启动时执行的命令,不占用存储空间。<missing> 4 days ago RUN /bin/sh -c yarn install --production # b… 85.3MB buildkit.dockerfile.v0
执行yarn install --production安装生产依赖的层,下载的依赖包占用85.3MB空间。<missing> 4 days ago COPY . . # buildkit 6.49MB buildkit.dockerfile.v0
将本地当前目录文件复制到容器/app目录的层,复制文件总大小6.49MB。<missing> 5 days ago WORKDIR /app 0B buildkit.dockerfile.v0
设置容器工作目录为/app的元数据层,后续指令默认在该目录下执行,不占用存储空间。<missing> 6 days ago /bin/sh -c #(nop) CMD ["node"] 0B
node:18-alpine镜像设置的默认CMD,用于启动node命令,属于基础镜像的元数据层。<missing> 6 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B
node:18-alpine镜像的ENTRYPOINT,用于处理node启动的入口脚本,属于基础镜像的元数据层。<missing> 6 days ago /bin/sh -c #(nop) COPY file:4d192565a7220e13… 388B
node:18-alpine镜像中复制docker-entrypoint.sh脚本的层,脚本大小388B。<missing> 6 days ago /bin/sh -c apk add --no-cache --virtual .bui… 7.77MB
node:18-alpine构建时安装编译依赖的层,安装的包占用7.77MB空间。<missing> 6 days ago /bin/sh -c #(nop) ENV YARN_VERSION=1.22.19 0B
node:18-alpine镜像设置YARN_VERSION环境变量的元数据层,不占用存储空间。<missing> 6 days ago /bin/sh -c addgroup -g 1000 node && addu… 117MB
node:18-alpine构建时添加node用户组、用户,并安装node二进制文件的层,占用117MB空间。<missing> 6 days ago /bin/sh -c #(nop) ENV NODE_VERSION=18.19.0 0B
node:18-alpine镜像设置NODE_VERSION环境变量的元数据层,不占用存储空间。<missing> 10 days ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
alpine基础镜像的默认CMD,用于启动sh终端,属于最底层基础镜像的元数据层。<missing> 10 days ago /bin/sh -c #(nop) ADD file:1f4eb46669b5b6275… 7.38MB
alpine基础镜像的根文件系统层,包含alpine系统的基础文件,大小7.38MB。
内容的提问来源于stack exchange,提问作者Ilya

