DockerFile指令详解
基础知识
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序 执行
- “#”表示注释
- 每一个指令都会创建提交一个新的镜像层
FROM 指定基础镜像
通过FROM
指定的镜像,可以是任何有效的基础镜像,但FROM
有以下限制:
Dockerfile
中第一条非注释命令必须是FROM
在一个
Dockerfile
文件中创建多个镜像时,FROM
可以多次出现。只需在每个新命令FROM
之前,记录提交上次的镜像IDtag
或digest
是可选的,如果不使用这两个值时,会使用 latest 版本的基础镜像
选择基础镜像的三个原则:
- 官方镜像优于非官方的镜像
- 固定版本的Tag,而不是每次都使用latest
- 功能满足,选择体积小的镜像
1 | 格式: |
MAINTAINER 维护者信息
1 | 格式: |
COPY 复制文件
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录
复制到新的一层的镜像内的<目标路径>
位置。
<源路径>
可以是多个,甚至可以是通配符,<目标路径>
可以是容器内的绝对路径,也可以是相对于工作目录的相对路径,目标路径不存在会自动创建。
此外,源文件的各种元数据都会保留。如读、写、执行权限、文件变更时间等。
1 | 格式: |
ADD 更高级的复制文件
ADD
指令和 COPY
的格式和性质基本一致。tar类型文件
会自动解压,可以访问网络资源。
在 Docker 官方的 【Dockerfile 最佳实践文档]】中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。而且ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。
因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。
1 | 格式: |
ENV 设置环境变量
ENV指令就是设置环境变量,后面的其它指令,还是运行时的应用,都可以直接使用这里定义的环境变量。
这个例子中演示了如何换行,以及对含有空格的值用双引号括起来的办法。
docker run的时候可以使用 -e 覆盖或者添加变量
1 | 格式: |
ARG 构建参数
ARG用于指定传递给构建镜像时的变量,使用 docker build
构建镜像时,可以通过 --build-arg <varname>=<value>
参数来指定或重设置这些变量的值。
1 | 格式: |
EXPOSE 暴露端口
EXPOSE 指令并不会让容器监听 host 的端口,如果需要,需要在 docker run
时使用 -p
、-P
参数来发布容器端口到 host 的某个端口上。
1 | 格式: |
USER 指定当前用户
USER 用于指定运行镜像所使用的用户,使用USER指定用户时,可以使用用户名、UID 或 GID,或是两者的组合。
使用USER指定用户后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT 都将使用该用户。镜像构建完成后,通过 docker run 运行容器时,可以通过 -u 参数来覆盖所指定的用户。
1 | USER user |
WORKDIR 指定工作目录
WORKDIR用于在容器内设置一个工作目录,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。WORKDIR 指定的工作目录,必须是提前创建好的,可以看成cd命令。
在使用 docker run
运行容器时,可以通过 -w 参数覆盖构建时所设置的工作目录。
1 | WORKDIR /a |
LABEL 为镜像添加元数据
LABEL用于为镜像添加元数据,元数以键值对的形式指定,一条LABEL可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。
推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像
1 | 格式: |
ONBUILD 镜像触发器
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
1 | 格式: |
RUN 构建执行命令
在镜像的构建过程中执行特定的命令,并生成一个中间镜像
- RUN 命令将在当前 image 中执行任意合法命令并提交执行结果
- RUN 指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定
--no-cache
参数,如:docker build --no-cache
1 | shell 格式 |
CMD 容器启动命令
CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
一个Dockerfile仅仅最后一个CMD起作用,docker run命令如果指定了命令会覆盖CMD命令。
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
1 | 格式: |
ENTRYPOINT 容器启动命令
ENTRYPOINT指定这个容器启动的时候要运行的命令,可以追加命令。
Dockerfile 中只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令。
ENTRYPOINT 与 CMD 非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而是追加,且会覆盖 CMD 命令指定的参数