Dockerfile 命令全集

Dockerfile 是一个文本文件,里面包含了一系列的指令(Instruction),用于自动化地构建一个 Docker 镜像。每一条指令都会在镜像上创建一个新的层(Layer)。


核心指令详解

1. FROM

功能:指定基础镜像。所有 Dockerfile 都必须以 FROM 指令开始(ARG 是唯一可放在它之前的指令)。
语法FROM <image>[:<tag>] [AS <name>]
示例

# 使用官方 Python 运行时作为基础镜像
FROM python:3.9-slim

# 使用 Alpine Linux 作为基础镜像,这是一个非常小的发行版
FROM alpine:3.14

# 多阶段构建中,为阶段命名
FROM node:14 AS build-stage
2. RUN

功能:在容器构建过程中执行命令。每条 RUN 指令都会在当前镜像的最顶层创建一个新层并提交结果。
语法

  • Shell 格式RUN <command> (在 shell 中运行,默认是 /bin/sh -c)
  • Exec 格式RUN ["executable", "param1", "param2"]
    示例
# Shell 格式 (常见)
RUN apt-get update && apt-get install -y nginx
RUN pip install -r requirements.txt

# Exec 格式 (用于避免 shell 处理字符串)
RUN ["/bin/bash", "-c", "echo hello world"]

# 最佳实践:合并命令以减少镜像层数
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        git \
        curl \
    && rm -rf /var/lib/apt/lists/* # 清理缓存以减小镜像体积
3. CMD

功能:提供容器启动时的默认执行命令。一个 Dockerfile 中只能有一条 CMD 指令,如果有多条,则只有最后一条生效。
主要作用:作为容器启动的默认命令。
语法

  • Exec 格式(推荐): CMD ["executable","param1","param2"]
  • Shell 格式: CMD command param1 param2
  • 作为 ENTRYPOINT 的参数: CMD ["param1","param2"]
    示例
# 运行一个可执行文件
CMD ["nginx", "-g", "daemon off;"]

# 使用 shell 格式,命令会被包装在 `/bin/sh -c` 中
CMD echo "Hello world"

# 如果 Dockerfile 有 ENTRYPOINT,则 CMD 作为其参数
CMD ["--help"]

注意docker run [image] [command] 中的 [command] 会覆盖 CMD 的内容。

4. ENTRYPOINT

功能:配置容器启动后运行的可执行程序。让容器表现得像一个可执行文件。
语法

  • Exec 格式(推荐): ENTRYPOINT ["executable", "param1", "param2"]
  • Shell 格式: ENTRYPOINT command param1 param2
    示例
# 将容器设置为一个 CLI 工具
ENTRYPOINT ["git"]
# 此时,运行 `docker run my-git-image status` 等价于 `git status`

# 通常与 CMD 搭配使用,使用 CMD 提供默认参数
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"] # 默认参数
# `docker run my-nginx` 会运行 `nginx -g 'daemon off;'`
# `docker run my-nginx -t` 会运行 `nginx -t`,覆盖 CMD
5. LABEL

功能:为镜像添加元数据(标签),是键值对的形式。
语法LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例

LABEL maintainer="your-email@example.com"
LABEL version="1.0"
LABEL description="This is a custom \
web application image."
# 推荐将所有标签合并到一个 LABEL 指令中,以减少镜像层数
LABEL maintainer="dev@example.com" version="2.1" description="My app"
6. EXPOSE

功能:声明容器在运行时监听的网络端口。这只是一个文档说明,并不会实际发布端口。实际端口映射需要在 docker run 时使用 -p 参数。
语法EXPOSE <port> [<port>/<protocol>...]
示例

EXPOSE 80      # 默认监听 TCP 端口
EXPOSE 80/tcp
EXPOSE 80/udp
EXPOSE 443
7. ENV

功能:设置环境变量。这个变量在构建阶段和容器运行时均可用。
语法

  • ENV <key> <value> (设置一个变量)
  • ENV <key>=<value> ... (设置多个变量,推荐)
    示例
ENV APP_HOME /app
ENV NODE_ENV production

ENV NODE_ENV=production APP_HOME=/app
# 在后续指令中使用
WORKDIR $APP_HOME
RUN echo $NODE_ENV
8. ADDCOPY

功能:将文件、目录或远程 URL 文件从构建上下文复制到镜像的文件系统中。

特性 COPY ADD
基本复制
解压本地 tar
从 URL 下载 ✅ (但不推荐,需手动解压)

语法ADD/COPY [--chown=<user>:<group>] <src>... <dest>
最佳实践优先使用 COPY,除非你需要 ADD 的自动解压功能。
示例

# 复制本地文件到镜像
COPY package.json ./
COPY ./src /app/src

# 复制并改变文件所属用户/组
COPY --chown=node:node . /app

# 使用 ADD 解压本地 tar 包
ADD application.tar.gz /app/

# 不推荐:从 URL 复制 (最好用 RUN curl 或 RUN wget 更透明)
ADD https://example.com/file.tar.gz /tmp/
9. WORKDIR

功能:设置后续指令(RUN, CMD, ENTRYPOINT, COPY, ADD)的工作目录。如果目录不存在,会自动创建。
语法WORKDIR /path/to/workdir
示例

WORKDIR /app
COPY . .      # 现在复制到 /app 目录下
RUN pwd       # 输出 /app
10. ARG

功能:定义在构建时使用的变量。使用 docker build --build-arg <varname>=<value> 传递。在容器运行时不可用。
语法ARG <name>[=<default value>]
示例

# 定义构建参数并设置默认值
ARG USER=admin
ARG VERSION=latest

# 使用 ARG 变量
FROM alpine:$VERSION
RUN adduser -D $USER
11. VOLUME

功能:在镜像中创建一个挂载点,用于持久化存储或与其它容器共享数据。
语法VOLUME ["/data"]
示例

VOLUME /var/log
VOLUME ["/var/www", "/var/log/nginx"]
12. USER

功能:指定后续指令(RUN, CMD, ENTRYPOINT)以什么用户身份运行。
语法USER <user>[:<group>]USER <UID>[:<GID>]
示例

# 创建一个用户
RUN groupadd -r app && useradd -r -g app app
# 切换用户
USER app
CMD ["python", "app.py"]
13. HEALTHCHECK

功能:告诉 Docker 如何测试容器是否仍在正常工作。
语法

  • HEALTHCHECK [OPTIONS] CMD command (设置检查容器健康度的命令)
  • HEALTHCHECK NONE (禁用从基础镜像继承的健康检查)
    示例
# 每 30 秒检查一次,超时时间为 30 秒,重试 3 次才判定为不健康
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
  CMD curl -f http://localhost/ || exit 1
14. SHELL

功能:覆盖用于命令的 shell 默认格式。主要用于 Windows 容器,但也可用于 Linux 容器切换默认 shell。
语法SHELL ["executable", "parameters"]
示例

# 在 Linux 中切换到 bash
SHELL ["/bin/bash", "-c"]
RUN echo $0 # 现在会输出 /bin/bash
15. STOPSIGNAL

功能:设置发送给容器以使其停止的系统调用信号。
语法STOPSIGNAL signal
示例

STOPSIGNAL SIGTERM
16. ONBUILD

功能:创建一个“触发器”指令,该指令不会在当前构建中执行,而是在另一个构建以当前镜像为基础镜像时被执行。
语法ONBUILD <INSTRUCTION>
示例

# 基础镜像的 Dockerfile
ONBUILD COPY . /app/src
ONBUILD RUN make /app

# 当基于上述镜像构建新镜像时,会自动触发 ONBUILD 指令

最佳实践总结

  1. 使用 .dockerignore:排除构建上下文中不需要的文件,加速构建过程,避免不必要的文件被复制。
  2. 多阶段构建:使用多个 FROM 指令,将编译环境和运行环境分离,最终只复制必要的文件到一个小体积的最终镜像中,极大减小镜像大小。
FROM node:14 AS build
WORKDIR /app
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html # 只复制编译好的文件
  1. 合并 RUN 指令:使用 &&\ 将多个命令合并为一个指令,减少镜像层数并清理缓存(如 apt-get/var/lib/apt/lists/)。
  2. 选择合适的基础镜像:优先选择官方、经过验证的镜像(如 alpine, slim 版本),它们通常更小、更安全。
  3. 明确镜像版本:避免使用 latest 标签,指定具体的版本号以保证构建的一致性。
  4. 优先使用 COPY:除非需要 ADD 的自动解压功能,否则使用更简单的 COPY
  5. 使用非 root 用户:在 RUN 创建用户并使用 USER 切换,以提高安全性。
  6. Docker入门
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐