FROM 指定基础镜像
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个redis镜像的容器,再进行修改一样,基础镜像是必须指定的。而 FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令。 在 Docker Store 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如nginx 、 redis 、 mongo 、 mysql 、 httpd 、 php 、 tomcat 等;如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像, 如ubuntu 、 debian 、 centos、 alpine 等这些操作系统的软件库 。
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
RUN 执行命令
RUN 指令是用来执行命令行命令的,在定制镜像时是最常用的指令之一
格式:
shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。
示例:RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
exec 格式:RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式
注意:
(1)Dockerfile 中每一个指令都会建立一层,应尽量合并相同或相关命令
COPY 复制文件
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
格式:
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
注意:
(1)<目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录;
(2)若需改变文件的所属用户及所属组,可以加上 --chown=<user>:<group>选项,COPY [--chown=<user>:<group>] <源路径>... <目标路径>;
ADD 更高级的复制文件
格式:与上列COPY格式相同
注意:
(1)如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去;
(2)ADD 包含了更复杂的功能,其行为不是很清晰。最适合使用 ADD 的场合,就是需要自动解压缩的场合。其余场合应尽量使用COPY命令;
(3)ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢;
CMD 容器启动命令
用于指定容器启动时执行的命令
格式:
exec 格式(推荐方式):CMD ["可执行文件", "参数1", "参数2"...]
示例:CMD ["executable","param1","param2"]
shell 格式:CMD <命令>
示例:CMD command param1 param2
参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数
示例: CMD ["param1","param2"] 提供给ENTERYPOINT的默认参数
注意:
(1)每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令;
ENV 设置环境变量
设置环境变量
格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
注意:
(1)设置环境变量后,支持环境变量的指令可直接使用所定义的环境变量。支持环境变量的指令:ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD;
ARG 构建参数
构建参数
格式:
ARG <参数名>[=<默认值>]
注意:
(1)构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的;
(2)Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖;
VOLUME 定义匿名卷
定义匿名卷。在容器运行时,我们应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
EXPOSE 声明端口
声明运行时容器提供服务端口
格式:
EXPOSE <端口1> [<端口2>...]
注意:
(1)在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE 的端口;
(2)要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射
WORKDIR 指定工作目录
指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录
格式:
WORKDIR <工作目录路径>
注意:
(1)为后续的RUN CMD ENTRYPOINT指定配置工作目录,可以使用多个WORKDIR指令,若后续指令用的是相对路径,则会基于之前的命令指定路径;
更多Dockerfile 指令与详解参考文章
Docker-从入门到实践 https://yeasy.gitbooks.io/docker_practice/image/dockerfile/