讲解
上一章的 FROM/COPY/CMD 之外,日常高频指令还有这些。RUN 在构建时执行命令(装包、编译),每条约产生一层——相关的安装命令用 && 串在一条 RUN 里,并在同一层里清理缓存(rm -rf /var/cache/apk/* 之类),否则清理动作产生的新层并不会缩小前面层的体积。WORKDIR 设定后续指令和容器启动的工作目录(不存在自动创建,比 RUN mkdir + cd 规范)。ENV 设置镜像级环境变量(构建期和运行期都可见),ARG 是仅构建期的参数(docker build --build-arg 传入),两者别混:密钥绝不能走 ARG,构建历史里可见。
ADD 与 COPY 功能重叠,ADD 多两个能力(自动解压本地 tar、支持 URL 下载),官方建议:能用 COPY 就用 COPY,只有需要自动解压时才用 ADD。EXPOSE 声明端口(文档作用,端口映射章讲过)。USER 切换运行身份(安全章节细讲,先记住:别用 root 跑服务)。VOLUME 声明挂载点(匿名卷自动创建),健康检查 HEALTHCHECK 定义容器「健不健康」的判定命令(Compose 的 depends_on 条件会用到)。
ENTRYPOINT 与 CMD 的关系是压轴知识点:ENTRYPOINT 定「主程序」,CMD 定「默认参数」,两者拼起来是最终启动命令。docker run 镜像名 后面追加的参数覆盖的是 CMD 部分——于是 ENTRYPOINT ["top"] + CMD ["-b"] 的镜像,run 时不加参数跑 top -b,加 -d 1 就跑 top -d 1,镜像变成了「带默认参数的命令」。纯应用镜像用 CMD 就够,工具型镜像(kubectl、curl 这类)用 ENTRYPOINT 更顺手。
示例
构建上下文:一个简单的静态站点:
mkdir -p webctx/html && printf '<h1>由 Dockerfile 构建的站点</h1>\n' > webctx/html/index.html
综合运用 WORKDIR、COPY、EXPOSE、HEALTHCHECK、CMD(exec 形式):
# context: webctx
FROM nginx:1.27-alpine
WORKDIR /usr/share/nginx/html
COPY html/ .
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://127.0.0.1/ >/dev/null || exit 1
CMD ["nginx", "-g", "daemon off;"]
构建、运行并验证健康检查生效(STATUS 列会出现 healthy):
cd webctx && docker build -t ohmydocs-verify-web:1.0 . && cd ..
docker run -d --name ohmydocs-verify-instr -p 18083:80 ohmydocs-verify-web:1.0
sleep 2 && curl -sf http://localhost:18083
ENTRYPOINT + CMD 的「默认参数」模式——构建一个参数可覆盖的小工具镜像:
mkdir -p toolctx && printf 'FROM alpine:3.21\nENTRYPOINT ["ping"]\nCMD ["-c", "3", "127.0.0.1"]\n' > toolctx/Dockerfile
cd toolctx && docker build -t ohmydocs-verify-pinger:1.0 . && cd ..
docker run --rm ohmydocs-verify-pinger:1.0 -c 1 127.0.0.1
清理运行中的容器:
docker rm -f ohmydocs-verify-instr
常见坑
- RUN 分层不清缓存:apt/apk 装完不在同一条 RUN 里清缓存,缓存文件永久留在镜像里徒增体积。
- 用 ENV 存密钥:ENV 会进入镜像配置,docker inspect、镜像层里都能看到——密钥用 secret 或运行时注入。
- ENTRYPOINT 用 shell 形式:ENTRYPOINT node app.js 经 sh 转包,追加参数的行为和信号传递都会变——一律 JSON 数组。
- HEALTHCHECK 写了但没看:healthy/unhealthy 状态在 docker ps 的 STATUS 列;unhealthy 时先 docker inspect --format '{{json .State.Health}}' 看失败输出。
小结
RUN/WORKDIR/ENV/ARG/COPY/EXPOSE/USER/HEALTHCHECK 各司其职;ENTRYPOINT 定程序、CMD 定默认参数;密钥不进 ENV/ARG。下一章用多阶段构建把镜像瘦下来。