📜 详解 Dockerfile 各个指令与参数

Dockerfile 是构建镜像的核心配置文件,它由一系列 Docker 指令(Instruction) 组成。每个指令对应一个镜像层(Layer),并定义了如何打包应用、安装依赖、设置环境等操作。

本文将详细讲解每个 Dockerfile 指令的语法、参数、使用场景及最佳实践


🧱 一、基础结构

# 注释说明
INSTRUCTION arguments
  • 每条指令生成一个只读镜像层(Layer)
  • 多条指令之间顺序很重要,会影响缓存和最终镜像大小

📘 二、常用指令详解

1. FROM —— 设置基础镜像

FROM [--platform=<platform>] <image> [AS <name>]

示例:

FROM golang:1.22 AS builder
FROM alpine:3.20
参数说明
--platform指定平台架构,如 linux/amd64, linux/arm64
AS <name>为当前阶段命名,用于多阶段构建

📌 注意: FROM 必须是 Dockerfile 中第一条有效指令。


2. RUN —— 在镜像中执行命令

RUN <command>
RUN ["executable", "param1", "param2"]

示例:

RUN apt-get update && apt-get install -y curl
RUN ["go", "build", "-o", "/app"]
类型说明
Shell 形式默认使用 /bin/sh -c 执行
Exec 形式推荐形式,兼容性更好

📌 最佳实践:

  • 将多个命令合并减少层数
  • 清理临时文件以减小镜像体积

3. CMD —— 容器启动默认命令

CMD ["executable","param1","param2"]
CMD command param1 param2
CMD ["param1","param2"] # 提供给 ENTRYPOINT 的默认参数

示例:

CMD ["/app"]
CMD ["nginx", "-g", "daemon off;"]

📌 注意:

  • CMD 可被运行时传入的命令覆盖
  • 一个 Dockerfile 中只能有一个有效的 CMD

4. ENTRYPOINT —— 容器入口点

ENTRYPOINT ["executable", "param1", ...]
ENTRYPOINT command param1 ...

示例:

ENTRYPOINT ["/app"]
ENTRYPOINT ["echo", "Hello"]
CMD ["World"]

📌 区别于 CMD:

  • ENTRYPOINT 不会被运行时命令覆盖,除非使用 --entrypoint
  • CMD 可作为 ENTRYPOINT 的默认参数

5. COPY —— 从主机复制文件到容器

COPY [--chown=<user>:<group>] <src>... <dest>

示例:

COPY . /app
COPY main.go /app/
COPY config/app.yaml /etc/app/
参数说明
--chown设置目标文件的拥有者(适用于 Linux 用户)

📌 推荐用法:

  • 优先使用 COPY 而不是 ADD,避免自动解压 tar 包带来的不确定性

6. ADD —— 更强大的复制功能(慎用)

ADD [--chown=<user>:<group>] <src>... <dest>

示例:

ADD app.tar.gz /app/
ADD https://example.com/file.txt /tmp/

📌 说明:

  • 支持远程 URL 下载 & 自动解压压缩包
  • 一般不推荐使用,除非你确实需要自动解压功能

7. WORKDIR —— 设置工作目录

WORKDIR /path/to/workdir

示例:

WORKDIR /app
COPY . .
RUN go build -o /app/app

📌 说明:

  • 后续所有 RUN, CMD, COPY 等指令都在此路径下执行
  • 如果目录不存在会自动创建

8. EXPOSE —— 声明容器监听端口

EXPOSE <port>[/<proto>] [<port>[/<proto>]...]

示例:

EXPOSE 80/tcp
EXPOSE 8080/udp 8000

📌 说明:

  • 仅作文档用途,不会真正打开端口
  • 实际运行容器时需通过 -p 映射端口

9. ENV —— 设置环境变量

ENV <key>=<value> ...

示例:

ENV PORT=8080
ENV DEBUG=true LOG_LEVEL=info

📌 说明:

  • 可在后续指令中使用 ${VAR} 替换
  • 也可以通过 docker run -e KEY=VALUE 覆盖

10. ARG —— 构建参数

ARG <name>[=<default value>]

示例:

ARG VERSION=dev
RUN echo "Build version: ${VERSION}"

构建时传递参数:

docker build --build-arg VERSION=1.0.0 -t myapp .

📌 说明:

  • ARG 仅在构建阶段可见
  • ENV 不同,不会出现在最终镜像中(除非显式写入)

11. LABEL —— 添加元数据

LABEL maintainer="[email protected]"
LABEL com.example.version="1.0"

📌 用途:

  • 标注作者、版本、项目信息等
  • 可用于 CI/CD 工具识别镜像来源

12. ONBUILD —— 子镜像自动触发的指令(较少使用)

ONBUILD RUN make /app

📌 说明:

  • 当当前镜像作为其他镜像的基础镜像时,这些指令会被触发执行
  • 使用频率较低,但可用于构建模板镜像

13. STOPSIGNAL —— 指定终止信号

STOPSIGNAL signal

示例:

STOPSIGNAL SIGINT

📌 说明:

  • 控制容器收到 docker stop 时发送什么信号
  • 默认是 SIGTERM

14. HEALTHCHECK —— 容器健康检查

HEALTHCHECK [OPTIONS] CMD command

示例:

HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost:8080/health || exit 1
参数说明
--interval检查间隔时间
--timeout单次检查超时时间
--start-period初期等待时间
--retries失败多少次判定为不健康

📌 作用:

  • 检测服务是否可用
  • 配合编排工具(如 Kubernetes)使用更佳

15. SHELL —— 指定 Shell 解析方式

SHELL ["executable", "parameters"]

示例:

SHELL ["powershell", "-Command"]
RUN echo Hello from PowerShell

📌 说明:

  • 修改默认 Shell(默认是 /bin/sh -c
  • 适用于 Windows 容器或自定义脚本环境

🧪 三、完整示例(多阶段 + distroless)

# 构建阶段
FROM golang:1.22 AS builder
ARG VERSION=dev
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -ldflags "-X main.Version=${VERSION}" -o /server

# 运行阶段
FROM gcr.io/distroless/static-debian12
COPY --from=builder /server /server
EXPOSE 8080
ENV PORT=8080
CMD ["/server"]

✅ 四、最佳实践总结

实践说明
使用多阶段构建减小镜像体积
使用 distroless 或 scratch更安全、轻量
尽量关闭 CGO减少动态依赖
合并 RUN 操作减少分层数量
编写 .dockerignore排除无用文件
使用 LABEL 记录元数据方便追踪与管理
设置 HEALTHCHECK提高可观测性

📚 五、参考资料


💬 六、定制你的专属 Dockerfile

如果你能提供以下信息,我可以为你定制一份专属的 Dockerfile:

  • 项目类型(CLI 工具、Web API、定时任务等)
  • 是否需要挂载配置文件或日志目录
  • 是否连接数据库或其他外部服务
  • 是否有特殊依赖或构建流程

欢迎留言或私信 😊


📌 七、结语

掌握 Dockerfile 的编写,是实现容器化部署的第一步。理解每条指令的作用和参数含义,可以帮助你构建出更加高效、安全、可维护的容器镜像。

每日更新-免费小火箭账号
不要错过任何机会,探索最新的应用和游戏,就在我们的平台。
立即访问
最后修改:2025 年 04 月 30 日
如果觉得我的文章对你有用,请随意赞赏