在Docker中,Dockerfile有哪些常见指令?
Dockerfile 是用于构建 Docker 镜像的文本文件,包含一系列指令,用于定义镜像的构建过程。以下是 Dockerfile 中最常见的指令及其作用:
1. FROM
(基础镜像指令,必选)
指定构建当前镜像的基础镜像,所有镜像都必须基于某个基础镜像构建(除了 scratch
空镜像)。
语法:
FROM <镜像名>:<标签>
# 示例:基于 Ubuntu 22.04 构建
FROM ubuntu:22.04
2. RUN
(执行命令指令)
在镜像构建过程中执行命令(如安装软件、创建目录等),命令执行结果会被打包到新镜像中。
有两种格式:
- shell 格式(类似终端命令):
RUN <命令> # 示例:安装 nginx RUN apt-get update && apt-get install -y nginx
- exec 格式(推荐,避免 shell 解析问题):
RUN ["可执行文件", "参数1", "参数2"] # 示例:创建目录 RUN ["mkdir", "-p", "/app/logs"]
3. WORKDIR
(工作目录指令)
为后续的 RUN
、CMD
、ENTRYPOINT
、COPY
、ADD
等指令设置工作目录(类似 cd
命令,但更稳定)。
语法:
WORKDIR <路径>
# 示例:设置 /app 为工作目录
WORKDIR /app
# 后续指令会在 /app 下执行
RUN touch test.txt # 实际创建 /app/test.txt
4. COPY
(复制文件指令)
将宿主机的文件/目录复制到镜像中指定路径。
语法:
COPY <宿主机路径> <镜像内路径>
# 示例:复制当前目录的 app.py 到镜像的 /app 目录
COPY app.py /app/
# 复制目录(会复制目录内所有内容,不含目录本身)
COPY src/ /app/src/
5. ADD
(增强复制指令)
功能类似 COPY
,但增加了额外特性:
- 若源路径是压缩包(如
.tar
、.zip
),会自动解压到目标路径; - 若源路径是URL,会下载文件到目标路径(不推荐,建议用
RUN wget
更灵活)。
语法:
ADD <源路径> <目标路径>
# 示例:解压 local.tar.gz 到 /app 目录
ADD local.tar.gz /app/
注意:优先使用 COPY
(更明确),仅在需要解压或下载时用 ADD
。
6. ENV
(环境变量指令)
设置环境变量,该变量会在镜像构建过程和容器运行时生效(可被容器内程序读取)。
语法:
# 单变量设置
ENV <键> <值>
# 多变量设置(换行分隔)
ENV <键1>=<值1> \
<键2>=<值2>
# 示例:设置 Python 环境变量
ENV PYTHON_VERSION=3.9 \
PATH="/usr/local/python3/bin:$PATH"
7. EXPOSE
(声明端口指令)
声明容器运行时对外暴露的端口(仅为文档说明,不实际映射端口到宿主机)。
语法:
EXPOSE <端口1> [<端口2> ...]
# 示例:声明容器会使用 80 和 443 端口
EXPOSE 80 443
注意:实际端口映射需在 docker run
时用 -p
或 -P
参数指定。
8. CMD
(容器启动命令)
指定容器启动时默认执行的命令,若启动容器时手动指定了命令,会覆盖 CMD
。
每个 Dockerfile 只能有一个 CMD
(多个则最后一个生效)。
格式:
- shell 格式:
CMD <命令>
- exec 格式(推荐):
CMD ["可执行文件", "参数1", "参数2"]
示例:
# 启动 nginx(前台运行,避免容器退出)
CMD ["nginx", "-g", "daemon off;"]
9. ENTRYPOINT
(入口点指令)
定义容器启动时的固定入口命令,与 CMD
配合使用时,CMD
会作为 ENTRYPOINT
的参数。
ENTRYPOINT
不会被启动时的命令覆盖(除非用 --entrypoint
参数强制替换)。
格式:
- exec 格式(推荐):
ENTRYPOINT ["可执行文件", "参数1"]
示例:
# ENTRYPOINT 作为固定命令,CMD 作为参数
ENTRYPOINT ["echo", "Hello"]
CMD ["World"] # 容器启动时执行:echo "Hello" "World" → 输出 Hello World
10. VOLUME
(数据卷指令)
声明容器中的持久化目录(数据卷),用于存储需要持久化的数据(如日志、数据库文件)。
语法:
VOLUME ["<路径1>", "<路径2>"]
# 示例:声明 /data 为数据卷
VOLUME ["/data"]
容器运行时,该目录会自动挂载为匿名卷(或通过 docker run -v
指定宿主机路径)。
11. USER
(用户指令)
指定后续指令(RUN
、CMD
、ENTRYPOINT
等)的执行用户(默认是 root),增强安全性。
语法:
USER <用户名/UID>
# 示例:创建 appuser 并切换到该用户
RUN useradd -m appuser
USER appuser
# 后续命令会以 appuser 身份执行
12. ARG
(构建参数指令)
定义构建时的临时变量(仅在 docker build
过程中生效,构建完成后消失),可通过 --build-arg
传递。
语法:
ARG <参数名>[=<默认值>]
# 示例:定义构建时的版本参数
ARG VERSION=1.0
# 构建时使用:docker build --build-arg VERSION=2.0 .
其他常见指令
LABEL
:为镜像添加元数据(如作者、描述),便于管理。LABEL maintainer="dev@example.com" \ description="A custom nginx image"
ONBUILD
:定义触发器,当当前镜像被用作其他镜像的基础镜像时,自动执行该指令。ONBUILD COPY app.py /app/ # 子镜像构建时会自动执行此 COPY
这些指令是构建 Docker 镜像的基础,合理组合可创建高效、可复用的镜像。实际使用中,需注意指令的执行顺序(Docker 按顺序执行)和分层缓存(相同指令可复用缓存,加速构建)。