Files
docker_practice/07_dockerfile
yeasy 08e981018e fix(content): 修正四处书内自相矛盾的技术断言
1. FROM「必须是第一条指令」(4.5、7.16、summary 三处)与本书 7.7.4「FROM 之前的
   ARG」整节直接冲突。官方 Dockerfile 参考写的是 "A Dockerfile must begin with a
   FROM instruction. This may be after parser directives, comments, and globally
   scoped ARGs",且 "ARG is the only instruction that may precede FROM"。三处
   一并改成「第一条构建指令」并点明例外。

2. 12 章小结把 USER Namespace 列进「默认启用」的一档,并写「容器 root ≠ 宿主机
   root」;而同章 12.2.2 明写 USER Namespace 默认**不**启用、需 userns-remap 显式
   开启,18.1 更直说「在默认情况下,容器内的 root 用户(UID=0)就是宿主机上的
   root 用户」。小结按正文口径改回——这条读反了会直接误判容器逃逸的风险面。

3. 11.5「目前支持三种日志驱动类型」是 Compose 早期文本的残留。官方支持 json-file、
   local、syslog、journald、gelf、fluentd、awslogs、splunk、etwlogs、gcplogs、
   none 共十余种,本书 19 章小结自己就列了六种。改为给出常见取值并链到官方清单。

4. 7.8 与 7.5 的示例注释建议 postgres:latest / redis:latest,而 4.1、7.10、
   7.16、7 章小结、4.5 全都要求避免 latest(7.8 同一文件第 177 行也写「避免
   latest」)。按全书口径改掉这两处。

另:ENV 的空格分隔旧写法(7.6 的「格式一」、附录四的 PG_MAJOR/PATH 示例)改为等号
形式并加注。BuildKit 的 LegacyKeyValueFormat 检查会报
"ENV key=value" should be used instead of legacy "ENV key value" format,
而本书 10.2 与 07 章 README 正是在推荐 docker buildx build --check。
2026-08-07 23:26:12 -07:00
..
2026-03-24 09:27:04 -07:00
2026-05-01 10:24:43 +00:00

第七章 Dockerfile 指令详解

什么是 Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的 指令 (Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

第四章中,我们通过 docker commit 学习了镜像的构成。但是,手动 commit 只能作为临时修补,并不适合作为生产环境镜像的构建方式。

使用 Dockerfile 构建镜像有以下优势:

  • 自动化:可以通过 docker build 命令自动构建镜像。
  • 可重复性:由于 Dockerfile 是文本文件,可以确保每次构建的结果一致。
  • 版本控制Dockerfile 可以纳入版本控制系统 (如 Git),便于追踪变更。
  • 透明性:任何人都可以通过阅读 Dockerfile 了解镜像的构建过程。

Dockerfile 编写哲学

在深入每个指令的细节之前,笔者想强调一个至关重要的原则:Dockerfile 不是脚本,而是镜像的“设计图”。这个区别决定了你如何思考每条指令的作用。

相比编写 Bash 脚本的思维(“按顺序执行这些命令”),Dockerfile 的思维应该是(“这一层镜像应该如何构建,下一层如何分层”)。这个思维转变会影响你的决策:

  • 合并命令:一个 RUN apt-get update && apt-get install ... 应该写在一起,而不是分开成多个 RUN 指令,因为它们是同一个“层”的逻辑
  • 选择合适的指令COPY vs ADDCMD vs ENTRYPOINT 这些选择不是随意的,而是根据镜像分层的语义来决定的
  • 优化镜像大小:最后才清理缓存、删除临时文件,让这些“瘦身”操作在同一层完成

这个章节将详细介绍各个指令。在学习指令语法时,请始终思考:“这个指令为什么要以这样的方式工作?如果我是 Docker,我应该如何设计它?”

Dockerfile 基本结构

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

可运行 docker buildx build --check 校验的完整 Dockerfile 示例与配套 index.html 保存在仓库中。它使用 scratch,因此结构检查不会解析远程基础镜像元数据。下面的围栏与该文件由测试强制保持一致。

FROM scratch

COPY index.html /index.html

指令详解

本章将详细讲解 Dockerfile 中的各个指令:

高级特性

本章还将介绍 Dockerfile 的高级特性:

参考与最佳实践

此外,我们还将介绍 Dockerfile 的最佳实践和常见问题。

使用 Dockerfile 构建镜像

构建镜像的基本命令格式为:

docker build [选项] <上下文路径/URL/->

例如,在 Dockerfile 所在目录执行:

docker build -t my-image:1.0 .

关于版本号最佳实践

本章中的 Dockerfile 示例使用的基础镜像标签遵循以下原则:

  • 通用标签(如 ubuntu:24.04alpinenginx):保持原样,无需修改
  • 基础镜像版本号(如 node:22python:3.12):使用主或次版本号而非完整版本号(patch),这样可以自动获取最新的补丁版本,确保获得安全更新
  • 避免:不建议使用 latest 标签和完整的 patch 版本号(如 20.10.0)作为基础镜像,因为这会导致构建的不可重现性或安全风险

读者在使用这些示例时,应根据实际生产环境需求选择合适的版本号。

更多关于 docker build 的用法,我们在实战中会结合具体指令进行演示。