Dockerfile 语法
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Docker 通过读取 Dockerfile 中的指令自动构建镜像。
基础结构
Dockerfile 一般分为四部分:
- 基础镜像信息:使用
FROM指令。 - 维护者信息:使用
LABEL指令(旧版本使用MAINTAINER)。 - 镜像操作指令:
RUN、COPY、ADD等。 - 容器启动时执行指令:
CMD、ENTRYPOINT。
指令详解
FROM
指定基础镜像,必须是 Dockerfile 的第一条指令(ARG 除外)。
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
- 示例:
FROM ubuntu:20.04
LABEL
给镜像添加元数据,用于替代旧的 MAINTAINER 指令。
LABEL <key>=<value> <key>=<value> ...
- 示例:
LABEL version="1.0" description="这是一个 Web 服务器"
RUN
用于执行后面跟着的命令行命令。有以下两种格式:
- Shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。 - Exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。尽量将多条命令合并,使用
&&连接,并用\换行。
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
ADD
ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。
- 区别:
ADD的源路径可以是 URL。- 如果源文件是一个 tar 压缩文件,
ADD会自动解压。
CMD
类似于 RUN 指令,用于指定容器启动时默认执行的命令。
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令提供默认参数
注意:如果 Dockerfile 中有多个
CMD指令,只有最后一个生效。CMD会被docker run之后的参数替换。
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
ENTRYPOINT ["<execute>", "<param1>", "<param2>", ...]
- 搭配使用:可以让镜像变成像命令一样使用,或者在启动时进行一些预处理工作。
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
ARG
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
ARG <参数名>[=<默认值>]
WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
WORKDIR <工作目录路径>
EXPOSE
声明端口。
EXPOSE <端口1> [<端口2>...]
- 作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 在运行时使用随机端口映射时,也就是
docker run -P时,会自动随机映射EXPOSE的端口。
VOLUME
定义匿名卷。
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
- 作用:避免重要的数据,因容器重启而丢失,这是非常致命的。避免容器不断变大。
USER
用于指定执行后续命令的用户和用户组(用户和用户组必须提前已经存在)。
USER <用户名>[:<用户组>]
HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
HEALTHCHECK [选项] CMD <命令>
ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 A)。当有新的 Dockerfile 使用 FROM A 基于 A 镜像构建时,这时候 A 镜像 Dockerfile 里的 ONBUILD 指定的命令才会执行。
ONBUILD <其它指令>
最佳实践
- 精简镜像用途:尽量让每个镜像的用途都比较集中单一,避免构造大而复杂、多功能的镜像。
- 选用合适的基础镜像:容器的核心是应用。选择过大的父镜像(如
Ubuntu系统镜像)会造成最终生成应用镜像的臃肿,推荐选用瘦身过的应用镜像(如node:slim),或者较为小巧的系统镜像(如alpine、busybox或debian)。 - 减少镜像层数:尽量合并
RUN指令,清理无用的缓存和文件。 - 使用 .dockerignore:忽略不需要发送给 Docker daemon 的文件。