是什么?
Dockerfile是一个包含所有可以用来组合镜像的命令的文本文档。可以通过dcoker build
命令从Dockerfile构建镜像。
docker build -f /path/to/a/Dockerfile .
-f 指定Dockerfile的路径
指令
# Comment # 使用#标识注释
FROM:指定基础镜像
FROM必须为第一条指令。
FROM <image>[:<tag>] [AS <name>]
: 设置基础镜像
- 不指定标签时,默认使用latest版本
MAINTAINER:维护者信息
Syntax: MAINTAINER <name>
RUN:执行命令
用于指定 docker build 过程中运行的程序,其可以是任何命令
-
RUN命令支持两种格式:shell格式和exec格式。
-
每条RUN指令将当前的镜像基础上的图层上执行指令,并提交为新的镜像,命令较长的时候可以使用\来换行。建议不要使用太多的RUN操作,考虑封装成shell脚本,或者用一条语句组装起来。所以正确写法应该是:
RUN buildDeps='gcc libc6-dev make' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \ && mkdir -p /usr/src/redis \ && rm -r /usr/src/redis \ && apt-get purge -y --auto-remove $buildDeps
shell 格式
Syntax: RUN <command>
示例:
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
- shell格式是以
/bin/sh -c
来运行它(推荐)- 这意味着此进程在容器中的
PID
不为 1,不能接收 Unix 信号(比如kill信号),因此,当使用docker stop <container>
命令停止容器时,此进程接收不到SIGTERM
信号;
- 这意味着此进程在容器中的
exec 格式
Syntax: RUN ["<executable", "<param1>", "<param2>"]
其中 <executable>
为要运行的命令
COPY:复制文本
复制本机文件到容器目录下
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
<源路径> 指本机的src目录,可以是多个、以及使用通配符,通配符规则满足Go的filepath.Match 规则,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目标路径>使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。
ADD:高级复制文件
复制本机文件到容器目录下,且支持从一个URL或一个tar文件拉取文件
- tar文件会自动解压为目录
- 原路径是URL时 ,下载后的文件权限自动设置为 600
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
命令COPY和ADD命令有什么区别?
一般而言,虽然ADD并且COPY在功能上类似。唯一区别在于是否支持从远程URL获取资源。COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中。
满足同等功能的情况下,推荐使用COPY指令。ADD指令更擅长读取本地tar文件并解压缩。
CMD:容器启动命令
在运行镜像文件启动容器时,指定默认要运行的程序,且其运行结束后,容器也将终止。?
- CMD指定的命令可被docker run时指定的cmd命令覆盖
- 可以存在多个
CMD
指令,但仅有最后一个会生效
Syntax
CMD <command>
CMD ["<executable", "<param1>", "<param2>"]
CMD ["<param1>", "<param2>"]
前两种语法格式的意义同 RUN
第三种语法则用于 ENTRYPOINT
指令提供默认参数
ENTRYPOINT:入口点
同CMD,指定容器启动程序及参数。
- 与
CMD
不同的是,由ENTRYPOINT
启动的程序不会被docker run
命令行指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给ENTRYPOINT
指定的程序 docker run
命令的--entrypoint
选项的参数可覆盖ENTRYPOINT
指令指定的程序- 可以存在多个
ENTRYPOINT
指令,但仅有最后一个会生效
Syntax:
ENTRYPOINT <command>
ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
命令CMD和ENTERYPOINT的关系
-
Dockerfile必须指定至少一个
CMD
或ENTERYPOINT
命令 -
ENTERYPOINT
的优先级高于CMD
,如果二者同时存在,且均使用数组的方式,那么CMD
的参数会在后面追加到ENTERYPOINT
命令(详见)
-
有多个时都只执行最后一个
ENV:设置环境变量
Syntax:ENV <key> <value> \ <key>=<value>
-
在其他指令中可以直接引用ENV设置的环境变量。
-
可以使用
docker run --env <key>=<value>
修改环境变量
ARG:构建参数
Syntax:ARG <name>[=<default value>]
: docker file
中的变量
与ENV不同的是,容器运行时不会存在这些环境变量。
可以用 docker build --build-arg <参数名>=<值>
来覆盖。
VOLUME:定义匿名卷
在制作镜像时挂载卷。会在宿主机上自动生成一个对应的共享目录。
- 一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统
- 修改卷后立即生效
- 卷的修改不影响镜像
Syntax:VOLUME ["/path"]
EXPOSE:暴露端口
容器监听的端口和协议,供容器外部连接使用。默认使用TCP
-
运行容器时可以通过制定
- p
重写该配置docker run -p 80:80/tcp -p 80:80/udp ...
Syntax:EXPOSE <port> [<port>/<protocol>...]
WORKDIR:指定工作目录
为后续命令指定工作目录
- 注意再次指定目录时如果是相对路径要基于之前的命令
Syntax:WORKDIR <工作目录路径>
USER:指定当前用户
指定容器运行时的用户名或UID,后续的RUN也会使用指定的用户。
- 这个用户必须是事先建立好的,否则无法切换。
Syntax:USER <user>[:<group>] / <UID>[:<GID>]
HEALTHCHECK:健康检查
设置检查容器健康状况的命令
HEALTHCHECK [选项] CMD <命令>
HEALTHCHECK NONE
:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK 支持下列选项:
-
--interval=<间隔>
:两次健康检查的间隔,默认为 30 秒; -
--timeout=<时长>
:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒; -
--retries=<次数>
:当连续失败指定次数后,则将容器状态视为 unhealthy ,默认 3次。 -
command 的 exit status 表明容器的健康状态
0
: success1
: unhealthy2
: reserved - do not use this exit code (可以自己定义)
-
例子(\ 表示换行)
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
执行exit可使shell以指定的状态值退出。
LABEL:镜像标签
LABEL <key>=<value> <key>=<value> ...
: 镜像标签,方便使用
ONBUILD:定义触发器
Syntax
ONBUILD <INSTRUCTION>
Dockerfile作为镜像文件,会作为base image被另一个Dockerfile使用,来构建新的镜像文件。在新镜像文件执行FROM
时,会触发base image的Dockerfile中定义的触发器
- 尽管任何指令都可以注册成为触发器指令,但
ONBUILD
不能自我嵌套,且不会触发FROM
和MAINTAINER
指令 - 使用包含
ONBUILD
指令的Dockerfile
构建的镜像应该使用特殊的标签,例如ruby:2.0-onbuild
- 在
ONBUILD
指令中使用ADD
或COPY
指令应该格外小心,因为新构建过程的上下文在缺少指定原文件时会失败
参考:
https://www.jianshu.com/p/168fbb97b447
https://www.jianshu.com/p/ed4818838385
https://www.jianshu.com/p/c39e32396319
https://docs.docker.com/engine/reference/builder/