在运维工作中,Dockerfile 是构建 Docker 镜像的核心文件,通过一系列指令定义镜像的构建步骤和运行时配置。以下是 Dockerfile 中 20+ 常见指令的分类详解,结合示例说明其用途、注意事项及最佳实践:
一、基础镜像与维护者信息
1. FROM
作用:指定基础镜像,是 Dockerfile 的首个必需指令。
语法:
FROM <image>[:<tag>] [AS <name>]  # tag 默认为 latest
示例:
FROM python:3.9-slim  # 使用官方 Python 3.9 轻量镜像
FROM ubuntu:20.04 AS builder  # 定义构建阶段别名(用于多阶段构建)
注意:
- 尽量使用官方镜像或经过验证的基础镜像(如 Alpine 镜像体积更小);
- 避免使用 latest标签,确保版本确定性。
2. LABEL
作用:为镜像添加元数据(如作者、版本、描述等),便于管理。
语法:
LABEL <key>=<value> <key>=<value> ...
示例:
LABEL maintainer="doubao@example.com"
LABEL version="1.0.0" description="My web application"
注意:
- 推荐使用单个 LABEL指令减少镜像层数;
- 元数据可通过 docker inspect查看。
二、文件操作指令
3. COPY
作用:从宿主机复制文件/目录到镜像中。
语法:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
示例:
COPY requirements.txt /app/  # 复制单个文件
COPY src/ /app/src/         # 复制目录(递归)
COPY --chown=www-data:www-data index.html /var/www/html/  # 指定文件所有者
注意:
- 源路径必须在构建上下文(docker build命令的路径参数)内;
- 目标路径若不存在会自动创建。
4. ADD
作用:类似 COPY,但支持远程 URL 和自动解压 tar 文件。
语法:
ADD [--chown=<user>:<group>] <源路径>... <目标路径>
示例:
ADD https://example.com/app.tar.gz /app/  # 下载并解压远程文件
ADD package.tar.xz /opt/  # 自动解压 tar 文件
注意:
- 优先使用 COPY(语义更明确,仅复制文件);
- 避免使用 ADD处理远程 URL(可能导致缓存失效)。
5. VOLUME
作用:定义容器运行时的挂载点,用于持久化数据。
语法:
VOLUME ["/data"]  # 支持单个路径或多个路径
示例:
VOLUME /var/lib/mysql  # 持久化 MySQL 数据目录
注意:
- 数据卷内容不会打包到镜像中;
- 推荐在 docker run时通过-v或--mount显式挂载。
三、环境配置指令
6. ENV
作用:设置环境变量,可在后续指令或运行时使用。
语法:
ENV <key>=<value> ...  # 推荐用此格式(单行多变量)
ENV <key> <value>      # 不推荐(可能导致空格解析问题)
示例:
ENV APP_ENV=production \DB_HOST=localhost \DB_USER=root
注意:
- 环境变量会持久化到镜像中,可通过 docker inspect查看;
- 可被 docker run -e覆盖。
7. ARG
作用:定义构建时参数,用于传递构建过程中的变量(如版本号)。
语法:
ARG <name>[=<default value>]
示例:
ARG VERSION=1.0.0
RUN echo "Building version $VERSION"
使用方式:
docker build --build-arg VERSION=2.0.0 .  # 构建时传递参数
注意:
- ARG定义的变量仅在构建时有效,运行时不可用;
- 若未提供默认值且未在构建时传递,则会报错。
四、执行命令指令
8. RUN
作用:在构建时执行命令(如安装软件、编译代码等),生成新的镜像层。
语法:
RUN <command>  # shell 格式(通过 /bin/sh -c 执行)
RUN ["executable", "param1", "param2"]  # exec 格式(更推荐,避免 shell 处理)
示例:
RUN apt-get update && apt-get install -y python3-pip  # shell 格式
RUN ["pip3", "install", "requests"]  # exec 格式
注意:
- 合并多行命令(如 &&连接)减少镜像层数;
- 清理缓存文件(如 apt-get clean)降低镜像体积。
9. CMD
作用:指定容器启动时默认执行的命令。
语法:
CMD ["executable", "param1", "param2"]  # exec 格式(推荐)
CMD ["param1", "param2"]  # 为 ENTRYPOINT 提供默认参数
CMD command param1 param2  # shell 格式(不推荐,可能导致信号处理问题)
示例:
CMD ["python3", "app.py"]  # 容器启动时执行 python3 app.py
注意:
- 一个 Dockerfile 只能有一个 CMD,多个则最后一个生效;
- 可被 docker run后的命令覆盖(如docker run myimage bash)。
10. ENTRYPOINT
作用:配置容器启动时执行的命令,不可被 docker run 后的命令覆盖(但参数可追加)。
语法:
ENTRYPOINT ["executable", "param1", "param2"]  # exec 格式(推荐)
ENTRYPOINT command param1 param2  # shell 格式(不推荐)
示例:
ENTRYPOINT ["python3", "app.py"]  # 固定执行 python3 app.py
CMD ["--port", "8080"]  # 为 ENTRYPOINT 提供默认参数
使用方式:
docker run myimage --port 8000  # 覆盖默认参数,执行 python3 app.py --port 8000
注意:
- ENTRYPOINT与- CMD常配合使用(- ENTRYPOINT定义命令,- CMD提供默认参数);
- 推荐使用 exec 格式避免 shell 处理。
五、网络与端口配置
11. EXPOSE
作用:声明容器运行时监听的端口(仅作文档用途,不实际映射端口)。
语法:
EXPOSE <port> [<port>/<protocol>]
示例:
EXPOSE 80/tcp  # 声明 HTTP 服务监听 80 端口
EXPOSE 53/udp  # 声明 DNS 服务监听 53 UDP 端口
注意:
- 实际端口映射需在 docker run时通过-p或-P实现;
- 支持同时声明多个端口(如 EXPOSE 80 443)。
六、用户与工作目录
12. WORKDIR
作用:设置后续命令的工作目录(若不存在则创建)。
语法:
WORKDIR /path/to/workdir
示例:
WORKDIR /app
COPY . .  # 相当于复制到 /app/
RUN pip install -r requirements.txt
CMD ["python", "app.py"]  # 工作目录为 /app
注意:
- 推荐使用绝对路径;
- 可在单个 Dockerfile 中多次使用,影响后续命令。
13. USER
作用:指定运行容器时的用户名或 UID(需先创建用户)。
语法:
USER <user>[:<group>]  # 或 <UID>[:<GID>]
示例:
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
CMD ["python", "app.py"]  # 以 appuser 身份运行
注意:
- 避免使用 root用户运行容器(安全风险);
- USER仅影响后续的- RUN、- CMD、- ENTRYPOINT指令。
七、多阶段构建(高级特性)
14. FROM ... AS <name>
作用:定义构建阶段,可在一个 Dockerfile 中使用多个 FROM 创建中间镜像,最终镜像仅包含所需层。
示例:
# 构建阶段:编译应用
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp# 运行阶段:仅包含运行时依赖
FROM alpine:3.14
WORKDIR /app
COPY --from=builder /app/myapp .  # 从 builder 阶段复制二进制文件
CMD ["./myapp"]
优势:
- 大幅减小最终镜像体积(无需包含编译工具);
- 无需在宿主机安装编译环境。
八、其他指令
15. HEALTHCHECK
作用:配置容器健康检查命令,用于监控容器状态。
语法:
HEALTHCHECK [选项] CMD <command>  # 检查容器健康状态的命令
HEALTHCHECK NONE  # 禁用基础镜像中的健康检查
示例:
HEALTHCHECK --interval=30s --timeout=5s \CMD curl -f http://localhost/ || exit 1
选项说明:
- --interval:检查间隔(默认 30s);
- --timeout:超时时间(默认 30s);
- --retries:连续失败多少次后标记为不健康(默认 3 次)。
16. STOPSIGNAL
作用:指定停止容器时发送的系统信号(如 SIGTERM、SIGKILL)。
语法:
STOPSIGNAL signal
示例:
STOPSIGNAL SIGINT  # 相当于 Ctrl+C
17. ONBUILD
作用:定义当该镜像被用作其他镜像的基础镜像时,自动执行的命令。
语法:
ONBUILD <INSTRUCTION>
示例:
ONBUILD COPY . /app  # 当此镜像被继承时,自动复制当前目录到 /app
ONBUILD RUN npm install  # 自动安装依赖
注意:
- ONBUILD指令不会在当前镜像构建时执行,而是在继承该镜像的子镜像构建时执行;
- 谨慎使用,可能导致意外行为。
九、最佳实践建议
- 
减少镜像层数: - 合并 RUN命令(如apt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/*);
- 使用多阶段构建分离编译环境与运行环境。
 
- 合并 
- 
合理使用缓存: - 不变的内容(如依赖安装)放在 Dockerfile 前面;
- 频繁变更的内容(如源代码)放在后面。
 
- 
安全优化: - 避免使用 root用户运行容器;
- 最小化镜像权限(如删除不必要的工具)。
 
- 避免使用 
- 
体积优化: - 使用轻量级基础镜像(如 Alpine、Distroless);
- 清理构建过程中的临时文件和缓存。
 
十、常见指令对比表
| 指令 | 执行时机 | 是否生成镜像层 | 能否多次使用 | 用途 | 
|---|---|---|---|---|
| RUN | 构建时 | 是 | 是 | 执行命令(如安装软件) | 
| CMD | 运行时 | 否 | 否(仅最后一个生效) | 指定默认命令 | 
| ENTRYPOINT | 运行时 | 否 | 否(仅最后一个生效) | 配置容器启动命令 | 
| COPY | 构建时 | 是 | 是 | 复制文件/目录 | 
| ADD | 构建时 | 是 | 是 | 复制文件/目录(支持 URL 和解压) | 
| ENV | 构建时 | 是 | 是 | 设置环境变量 | 
| WORKDIR | 构建时 | 否 | 是 | 设置工作目录 | 
通过合理组合这些指令,可构建出高效、安全、可维护的 Docker 镜像。建议结合官方文档(https://docs.docker.com/engine/reference/builder/)深入学习各指令细节。
