Docker | Dockerfile
Contents
- FROM
- MAINTAINER
- RUN
- COPY
- ADD
- CMD
- ENTRYPOINT
- EXPOSE
- ENV
- ARG
- VOLUME
- WORKDIR
- ONBUILD
FROM
- 说明:FROM,指定镜像构建的基础镜像,每个Dockerfile都必须包含FROM指令,且为第一条指令。
- 格式:FROM [Image] 或 FROM [Image:tag]
- 示例:
- FROM scratch
- FROM centos:centos7
- 备注:
- 官方镜像
- 空白镜像:
scratch
scratch
: 虚拟的概念,不实际存在;以scratch为基础镜像意味着不以任何镜像为基础,接下来的构建质量将作为镜像的第一层存在。Go
开发的应用通常使用scratch作为基础镜像,go程序包含了运行所需的一切库文件。
MAINTAINER
- 说明:指定维护者信息
- 格式:MAINTAINER Name
- 示例:MAINTAINER zhezh.boy@gmail.com
- 备注:
RUN
- 说明:用来执行命令行命令。
切记
:每一层构建的最后一定要清理掉无关文件。 - 格式:
- shell:RUN [Command]
- exec:RUN [“可执行程序”, “参数”, “参数”]
- shell:RUN [Command]
- 示例:
RUN mkdir -p /home/api/ && \
touch /home/api/Caddyfile && \
touch /home/api/Dockerfile
- 备注:
- 在linux操作系统上默认 /bin/sh
- 多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN书写时的换行符是
\
|
|
COPY
- 说明:COPY:指令将镜像构建的上下文目录中
[源路径]
表示的文件或目录拷贝到新一层的镜像的[目标路径]
中去。 - 格式:
- shell: COPY [源路径] [目标路径]
- exec: COPY [“源路径”], [“目标路径”]
- 示例:
- COPY run.sh /home/api/
- 备注:
- 有关 上下文 解释在这里
- 源路径:可以是多个,也可以是通配符(满足Go的filepath.Match规则)
- COPY hom* /mydir/
- COPY hom?.txt /mydir/
- 目标路径:可以是容器内的绝对路径,也可以是相对于工作目录( WORDDIR 指定工作目录 )的相对路径;目标路径不存在,则创建;COPY会保留源文件属性。
- Best practices for writing Dockerfiles 中建议尽量使用COPY, 并使用RUN & COPY的组合来代替ADD, 建议只在复制tar文件时使用ADD
ADD
- 说明:添加文件或文件夹到容器
- 格式:ADD [src] [dest]
- 示例:ADD api.tar.gz /home/api/
- 备注:ADD和COPY类似,区别在于
- ADD会自动解压文件,而COPY只是文件拷贝
- 此外ADD的
[源路径]
可以是URL
|
|
CMD
- 说明:容器
运行时
执行的命令,但是一个Dockerfile中只能有一条CMD命令,多条则执行最后一条CMD命令。 - 格式:
- shell:CMD [command] [para1] [para2]
- exec:CMD [“exec”, “para2”, “para2”]
- 参数列表:CMD [“参数1”,“参数2”, …]
- 示例:
- CMD [“/usr/bin/mongod”, “-f”, “/etc/mongod.conf”]
- CMD [“C:\MongoDB\bin\mongod.exe”, “-f”, “D:\mgo\conf\mongod.conf”]
- CMD [“-f”, “/etc/mongod.conf”]
- 备注:
- Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的
- 当 docker run command 的命令匹配到 CMD command 时,会替换CMD执行的命令。
- 在指令格式上,一般推荐使用
exec
格式,这类格式会被daemon解析为Json数组,因此一定要使用双引号"
, 而不要使用单引号。例如- CMD echo $HOME, 在实际执行中会被解析为:
- CMD [ “sh”, “-c”, “echo $HOME” ]
- 容器中的应用只有前台执行,容器内没有后台服务的概念;对于容器而言, 其启动程序就是容器运行的主进程,主进程执行完成,容器也就退出了。例如:
- 容器执行:CMD service mongod start
- 结果发现:容器执行后立即退出, 甚至systemctl命令根本就不能执行
- 原因分析:
- CMD service mongod start 被解析为:
- CMD [ “sh”, “-c”, “service mongod start” ]
- 此时,主进程其实为
sh
, 当service命令执行完成后,sh也就结束了,即sh作为主进程退出, 随之容器也退出。
- 正确的做法:直接执行mongod可执行文件,并且要求以前台方式执行。例如
- CMD [“mongod”, “-f”, “/etc/mongod.conf”]
- ENTRYPOINT & CMD 同时使用时,可用ENTRYPOINT来执行服务的可执行程序(monogd), CMD来执行服务启动的参数。例如:
- ENTRYPOINT [“mongod”]
- CMD [“-f”, “/etc/mongod.conf”]
- Link
ENTRYPOINT
- 说明:容器入口点。container
启动时
执行的命令,但是一个Dockerfile中只能有一条ENTRYPOINT命令,多条则只执行最后一条;不可以被容器运行时的命令所覆盖。 - 格式:
- exec:ENTRYPOINT [“可执行程序”, “参数1”, “参数2”]
- shell:ENTRYPOINT [command] [para1] [para2]
- 示例:
- ENTRYPOINT [“mongod”, “-f”, “/etc/mongod.conf”]
- 备注:
- ENTRYPOINT没有CMD的可替换特性
- 当指定ENTRYPOINT后,CMD不在执行命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令
- 可在docker run命令时使用–entrypoint指定(但是只能用写法一)
- ENTRYPOINT有两种写法,第二种(shell form)会屏蔽掉docker run时后面加的命令和CMD里的参数
EXPOSE
- 说明:暴露容器的端口
- 格式:EXPOSE [port] [port]…
- 示例:EXPOSE 80
- 备注:Docker中有两种暴露端口方式:
- EXPOSE: 隐式暴露,只在Dockerfile中出现,所暴露的端口只是被其他容器使用(Docker容器内部使用)
- PUBLISH:显示暴露,供外部网络使用;PUBLISH只是一个概念,在Dockerfile中没有具体指令,是通过docker run 的参数 -p 或 -P,或者docker-compose中的ports来体现的
- -P:自动映射,
- -p:固定映射,格式:-p 宿主端口:容器端口
ENV
- 说明:设置环境变量
- 格式:
- ENV [key] [value]
- ENV [“key1=value1”] [“key2=value2”]
- 示例:
- ENV APIVersion=1.0 APIHome=/home/api/
- 备注:ENV设置的环境变量和Shell中的用法一样,通过
$APIVersion
获取值
ARG
- 说明:设置 docker build 时的参数
- 格式:ARG [参数名] [=默认值]
- 示例:ARG user=boyzhe
- 备注:
- ARG 命令设置的环境变量只在build时有效,在容器运行时是不会存在这些变量的
- ARG 指令是定义参数名称,以及默认值;该默认值在build时可通过 –build-arg <参数名>=<参数值>来覆盖
- 如果在build镜像时指定了一个在Dockerfile中不存在的 ARG 参数,则会出现一个Warning.
VOLUME
- 说明:创建挂载点,可用来让其他容器挂载以实现数据共享或对容器数据的备份、恢复或迁移
- 格式:
- VOLUME [path]
- VOLUME [“path1”, “path2”…]
- 示例:
- VOLUME /home/mongo/data /home/mongo/log
- 备注:
- 容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失, 所以当数据需要持久化时用这个命令。
- Dockerfile中使用VOLUME挂载目录和docker run时通过-v参数指定的挂载目录有何不同?
- 主要的不同点就是docker run的-v参数可以指定挂载到宿主机的那个目录, 而Dockerfile的VOLUME不能,其在宿主机上的挂载目录是随机生成的。
-v
参数格式及实例- docker run -v host_dir|file:container_dir|file
WORKDIR
- 说明:设置工作目录
- 格式:WORKDIR [path]
- 示例:WORKDIR /home/mongo/
- 备注:
- 可以使用绝对路径,也可以使用相对路径,设置之后的所有操作都将在这个目录下完成
- 设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。
ONBUILD
- 说明:用来设置一些触发指令, 这些指令在当前镜像构建时不会被执行, 只有当以当前镜像为基础镜像, 去构建下一级镜像的时候才会被执行
- 格式:ONBUILD [其他指令]
- 示例:
- ONBUILD COPY run.sh /home/api/
- ONBUILD RUN [“apt-get”, “install”, “vim”]
- 备注:
See Also
Thanks to the authors 🙂