Dockerfile
Dockerfile可以分成4部分:基础镜像,维护者信息,镜像操作指令,启动命令
| 指令 | 作用 |
|---|---|
| FROM | 指定基础镜像 |
| LABEL | 打标签,k=v形式。多个kv之间空格隔开。v如果有空格等特殊字符,用“”引起。 |
| MAINTAINER | 指定维护者信息,已经过时,可以使用LABEL maintainer=xxx 来替代 |
| ENV | 环境变量,给RUN和CMD命令使用。会固化到镜像的ContainerConfig里 |
| ARG | 指定构建参数。声明后的RUN命令才能使用。可以在build时,通过设置–build-arg来更改 |
| USER | 切换用户,他以后的命令都是以该用户运行。USER 1000:1000 |
| RUN | build镜像期运行的命令。多个RUN指令之间没有关系。有关系要在同一个RUN使用&& |
| ADD | 复制上下文中的文件进容器 |
| COPY | 复制上下文中的文件进容器 |
| CMD | |
| ENTRYPOINT | |
| WORKDIR | 指定以后命令的运行目录,不存在会创建 |
| VOLUME | 挂载,相当于run的-v参数。 |
| EXPOSE | 暴露端口,这只是一个声明。给用户看的而已。docker run -P的时候自动绑定端口,也会使用这个配置。 |
ENV vs ARG
- ENV在构建期和运行期都能生效。ARG只在构建期生效
- ENV的值不能在build时修改,ARG可以通过–build-arg来更改
- ENV的值可以在run时修改,通过-e参数
ADD vs COPY
ADD复制的如果是压缩包自动解压,如果是远程包,自动下载。
VOLUME
注意:一旦容器内的目录被挂载出去,VOLUME命令之后的对目录的所有修改操作,不会再影响挂载出去的目录。
所以,一般把VOLUME指令放在所有变更命令的后面
RUN
指令的写法又两种:shell写法和exec写法。
shell写法:
RUN
exec写法
RUN [“命令”,“参数1”, “参数2”]
区别:
如果命令中有环境变量,exec写法取不到ENV环境变量
CMD && ENTRYPOINT
ENTRYPOINT和CMD的作用都是容器的启动命令。看起来有一些重复。但是他们还是有一些微妙的区别。
ENTRYPOINT是真正的门,真正的入口。
覆盖
ENTRYPOINT或者CMD命令会自动覆盖之前的ENTRYPOINT或者CMD命令。
所以,在docker镜像运行时, 我们可以在命令指定具体命令, 覆盖在Dockerfile里的命令.
比如,这样的一个Dockerfile
1 | FROM ubuntu:trusty |
默认运行这个镜像是ping 本机。
我们可以在执行时覆盖这个默认命令。比如用hostname命令替换ping命令。
1 | # docker run demo:1.0 hostname |

ENTRYPOINT也是一样的,只不过覆盖时要用–entrypoint
1 | FROM ubuntu:trusty |
1 | # docker run --entrypoint hostname demo:1.0 |
所以,CMD命令更容易被docker run命令的方式覆盖。相反, 如果你希望你的docker镜像只执行一个具体程序, 不希望用户在执行docker run的时候随意覆盖默认程序. 建议用ENTRYPOINT.
两种写法
CMD和ENTRYPOINT指令的也是有两种格式写法。shell写法和exec写法。
上面例子是Exec写法。
这两种写法是有一个本质区别的。
同样是ping localhost。用exec写法启动的容器
1 | # docker exec caed34225b48 ps -f |
可以看到PID 1启动的就是ping命令。
再看下shell写法的结果
1 | # docker exec 545269dc6d49 ps -f |
可以看到PID 1启动的其实是sh程序,我们的ping命令作为sh的子程序运行了。
这样会导致的一个问题是,你从外部发给容器的POSIX信号,是被sh接收的,而sh命令并不会将信号转发给ping命令,会导致不能安全的关闭容器。比如用shell方法启动的容器一直在运行,我按Ctrl +C是无法停止的。
总结:exec写法不是bin/sh -c执行的,取不出环境变量的值。
所以最好时使用exec写法。
最终的用法:组合使用
从上面所知,ENTRYPOINT 用于指明程序必须运行的命令。CMD又比较方便覆盖。所以,我们可以将其联合使用,指定必须运行的命令。同时运行用户覆盖一些参数。ENTRYPOINT和CMD同时存在时, docker把CMD的命令拼接到ENTRYPOINT命令之后。
比如
1 | FROM ubuntu:trusty |
这样就运行用户自己指定运行的次数。
1 | docker run demo:1.0 5 |