在 Docker 镜像与容器 一节中我们通过 Dockerfile 构建了镜像,这节我们来了解下 Dockerfile 的语法。Dockerfile 包含了诸多关键字,所以要学习 Dockerfile 的用法,得先从这些关键字入手。
FROM
位于 Dockerfile 开头,表示基于什么镜像构建:
| 12 | FROM scratch # 制作 base imageFROM ubuntu:16.04 #使用 ubuntu:16.04 这个 image | 
|---|
出于安全考虑,最好使用官方的 image 作为 base image。
LABEL
Dockerfile 的元数据,描述作用。
| 1 | LABEL version=”1.0” author=”mrbird” description=”dockerfile demo” | 
|---|
Dockerfile 最好都要有元数据,这样更易于理解。
RUN
运行命令,每次 run 都会生成一个图层,所以最好将命令合并:
| 123 | FROM ubuntuRUN apt-get update \ && apt-get install -y vim | 
|---|
\换行
WORKDIR
用于指定工作目录,切换路径:
| 1234 | FROM ubuntuWORKDIR /test # 没有则自动创建 test 目录 WORKDIR demoRUN pwd | 
|---|
输出 /test/demo。
最好不要用 RUN cd 来切换目录,而使用 WORKDIR,这样可以减少不必要的图层,尽量使用绝对目录。
ADD & COPY
ADD 和 COPY 都可以将构建环境中的文件或目录复制到镜像中,比如
| 12 | WORKDIR /demoADD test test/ | 
|---|
| 12 | WORKDIR /demoCOPY test test/ | 
|---|
最终都会将 test 文件添加到/demo/test/目录下。
区别:
- ADD 添加的文件是压缩文件的话,会自动解压。
- COPY 只能复制构建目录下的文件,ADD 可以添加一个构建上下文中的文件或目录,也可以是一个 URL,如:1 ADD http://wordpress.org/latest.zip / 
ENV
设置环境变量常量。
| 12 | ENV MYSQL_VERSION 5.7RUN apt-get install -y mysql-server=”${MYSQL_VERSION}” | 
|---|
通过设定常量,可以提高可维护性。
VOLUME & EXPOSE
存储和网络,这里先略,后面学习到这一块再说。
CMD
- 设置容器启动后默认执行的命令和参数。
- docker run 指定了其他命令,CMD 命令会被忽略。
- 定义了多个 CMD,只有最后一个有效。
比如有如下 Dockerfile:
| 1234 | FROM ubuntuENV name mrbirdCMD echo “hello docker”CMD echo “hello $name” | 
|---|
构建镜像,运行:
| 1 | docker run [image] | 
|---|
输出 hello mrbird。
如果运行:
| 1 | docker run -it [image] /bin/bash | 
|---|
则没有输出。
ENTRYPOINT
- 设置容器启动时运行的命令。
- 不会被忽略,一定会执行。
- 一般写一个 shell 脚本作为 ENTRYPOINT。
比如 mongodb 官方 Dockerfile 末尾一段:
| 12345 | COPY docker-entrypoint.sh /usr/local/bin/ENTRYPOINT [“docker-entrypoint.sh”]EXPOSE 27017CMD [“mongod”] | 
|---|
ENTRYPOINT 和 CMD 结合使用有一个技巧:
比如有如下一个 Dockerfile:
| 123 | FROM ubuntuENTRYPOINT [“/bin/ls”]CMD [] | 
|---|
意思是在 ubuntu 这个镜像上构建,通过 ENTRYPOINT 运行/bin/ls 命令,然后CMD []这行可以介绍额外的参数选项。
通过这个 Dockerfile 构建镜像后(image id 为 95c35bb00761),分别运行下面这些命令来创建容器: ker
ker
可以看到我们通过相同的镜像构建出了不同的容器。
Shell 和 Exec 格式
在 Dockerfile 中,命令的写法有 Shell 格式和 Exec 格式:
Shell 格式的 Dockerfile 如下:
| 123 | RUN apt-get install -y vimCMD echo “hello world”ENTRYPOINTT echo “hello world” | 
|---|
Exec 格式如下所示:
| 123 | RUN [“apt-get”,”install”,”-y”,”vim”]CMD [“/bin/echo”,”hello world”]ENTRYPOINTT [“/bin/echo”,”hello world”] | 
|---|
在使用 Exec 格式的时候需要注意和常量的搭配使用问题,比如在 Shell 格式下:
| 123 | FROM ubuntuENV name mrbirdENTRYPOINTER echo “hello $name” | 
|---|
创建镜像,运行容器后输出:hello mrbird。
但是在 Exec 格式下:
| 123 | FROM ubuntuENV name mrbirdENTRYPOINTER [“/bin/echo”,”hello $name”] | 
|---|
创建镜像,运行容器后输出:hello $name。
正确的写法是:
| 123 | FROM ubuntuENV name mrbirdENTRYPOINTER [“/bin/bash”,”-c”,”echo hello $name”] | 
|---|
 
		 
                      