1. Dockerfile 自动化构建基础
- 定义与优势:Dockerfile 是一个包含构建镜像指令的文本文件,由 Docker 镜像构建器按顺序排列并执行。相比手动
docker commit,它使任务变得可重复且易于版本控制。 - 构建命令:使用
docker build命令启动构建进程。 - 缓存机制:构建程序会检查每条指令是否已有缓存。如果指令未改变,它会跳过执行以节省时间;如果某一步发生改变,后续所有步骤的缓存都会失效。
2. 核心指令详解
本章将 Dockerfile 指令分为两类:元数据指令和文件系统指令。
- 元数据指令(Metadata Instructions):
FROM:指定基础镜像,是每个 Dockerfile 的第一条指令(除注释外)。MAINTAINER:设置镜像维护者的元数据信息。ENV:设置环境变量,这些变量在构建过程中及运行容器时都有效。LABEL:以键值对形式记录镜像的额外元数据。WORKDIR:为后续的RUN、CMD、ENTRYPOINT指令设置工作目录。EXPOSE:声明容器在运行时监听的网络端口。USER:指定运行镜像时使用的非 root 用户或 UID。
- 文件系统指令(Filesystem Instructions):
RUN:在当前镜像之上的新层中执行命令并提交结果。COPY:从构建上下文的主机系统复制文件或目录到镜像中。ADD:类似于COPY,但功能更强,可以处理远程 URL 和自动解压压缩包。VOLUME:在镜像中创建挂载点,用于持久化数据或共享数据。ENTRYPOINT:配置容器启动时默认执行的可执行程序。
3. 构建触发器:ONBUILD
- 功能:
ONBUILD指令允许你定义在当前镜像被用作另一个构建的基础镜像(下游镜像)时才执行的操作。 - 应用场景:常用于创建“平台镜像”(如 Java 或 Node.js 开发环境),当开发者基于此镜像构建具体的应用代码时,才触发源码复制和编译等操作。
4. 容器启动管理与多进程
- 启动脚本:使用启动脚本(Entrypoint scripts)可以在主进程启动前验证环境先决条件(如数据库是否就绪)。
- 初始化进程(Init):对于需要管理多个进程或需要僵尸进程清理功能的容器,推荐使用轻量级初始化系统(如
runit或supervisord)作为ENTRYPOINT。
5. 镜像加固与安全性(Hardening)
- 内容可寻址标识符(CAID):通过在
FROM指令中使用镜像的哈希值(Digest)而非标签,可以确保基础镜像的完整性,防止被篡改。 - 最小权限原则:强烈建议在 Dockerfile 中使用
USER指令切换到非 root 用户运行应用,以减少攻击面。 - 清理 SUID/SGID:为了防止提权风险,应在构建过程中删除不必要的具有 SUID 或 SGID 权限的文件。
比喻理解:
如果说第7章的手动构建像是通过“拍照留念”来记录你装修房子的每一步,那么第8章的 Dockerfile 就像是一张“自动化施工蓝图”。你只需要把装修步骤(指令)写在图纸上,Docker 施工队就能自动为你盖好房子。而 ONBUILD 就像是预留在地基里的接口,只有当别人想在你的地基上盖二楼时,这些预设的机关才会启动。