前言
构建或者修改Docker image建议都使用Dockerfile。因为通过Dockerfile构建image或者修改image是透明的、可记录的,且无需重复的镜像和容器的创建过程。甚至可以使用版本控制(如:git)来保存Dockerfile的修改记录,以保留docker image完整的生命周期。
Dockerfile基本语法
Dockerfile支持的语法命令如下:
INSTRUCTION argument
指令不区分大小写。但是,命名约定全部为大写。
所有Dockerfile都必须以FROM
命令开始。FROM
命令会指定基于哪个基础镜像创建,接下来的命令也会基于这个基础镜像。FROM
命令可以多次使用,表示会创建多个镜像。集体突发如下:
FROM <IMAGE NAME>
例如:
FROM ubuntu
上面的指定告诉我们,新的镜像将基于Ubuntu的镜像来构建。
继FROM
命令,Dockerfile还提供了一些其他的命令以实现自动化。这些命令的顺序就是他们的执行顺序。
MAINTAINER
MAINTAINER
命令用来设置改镜像的作者。语法如下:
MAINTAINER <author name>
例如:
MAINTAINER zacard
RUN
RUN
有2种形式,shell和exec。shell形式的语法如下:
RUN <command>
exec形式的语法如下:
RUN ["executable","param1","param2"]
ADD
ADD
复制文件的命令。它有2个参数
ADD <source> <destination>
CMD
CMD
提供了容器默认的执行命令。Dockerfile只允许使用一次CMD
命令。使用多个CMD
会抵消之前所有的命令,只有最后一个命令生效。CMD
命令有3种形式:
// exec形式,推荐的使用形式
CMD ["executable","param1","param2"]
// 默认ENTRYPOINT的param形式
CMD ["param1","param2"]
// shell形式
CMD command param1 param2
ENTRYPOINT
ENTRYPOINT
命令配置给容器一个可执行的命令,使镜像创建容器时默认运行一个可执行文件。且和CMD
类似,Dockerfile也只允许一个ENTRYPOINT
命令,多个ENTRYPOINT
只会执行最后一个命令。语法如下:
// exec形式,推荐的使用形式
ENTRYPOINT ["executable","param1","param2"]
// shell形式
ENTRYPOINT command param1 param2
CMD和ENTRYPOINT如何相互影响
2个命令相互间的影响如下表格所示:
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”,”p1_entry”] | |
---|---|---|---|
No CMD | error,not allowrd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“exec_cmd”,”p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry exec_cmd p1_cmd | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”,”p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry p1_cmd p2_cmd | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
另外,docker run命令中的参数会传递给ENTRYPOINT
命令,而不用担心被覆盖(CMD
与之相反)。所以ENTRYPOINT
与CMD
结合使用效果会更好。
EXPOSE
EXPOSE
命令指定容器在运行时监听的端口。语法如下:
EXPOSE <port> [<port>...]
例如:
// 映射容器私有端口80到共有端口8080
EXPOSE 80:8080
// 开放私有端口80
EXPOSE 80
注意,永远不要使用Dockerfile映射公有端口。不然你将可能只能运行一个容器化应用程序的实例。
WORKDIR
WORKDIR
命令指定了RUN
、CDM
和ENTRYPOINT
命令的工作目录。语法如下:
WORKDIR /path/to/workdir
ENV
ENV
命令设置环境变量。使用键值对的方式,增加了运行程序的灵活性。语法如下:
// 推荐
ENV <key>=<value>
ENV <key> <value>
USER
给镜像运行时设置一个UID。语法如下:
USER <uid>
VOLUME
授权访问从容器内到宿主主机上的目录。语法如下:
VOLUME ["/data"]
Dockerfile的一些建议
- 不要开机初始化
- 不要在构建中升级版本
- 使用小型基础镜像,建议
FROM alpine:3.3
- 尽量使用格式一致的Dockerfile,这样能使用缓存
- 不要在构建中升级版本,如在容器中
apt-get upgrade
- 使用特点的标签。如
FROM debian:jeesie
,而不是FROM debian
- 常见的命令组合。如:
apt-get update
与atp-get install
组合。此外使用\
格式化成多行命令。这样能够最大程度的应该缓存。 - 使用自己的基础镜像