Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像。
它是由多行命令组成,支持以#开头的注释行
配置指令
ARG
定义创建镜像过程中使用的变量
ARG <name> [=<default value>]
再执行docker build
时,可以通过-duild-arg[=]
来为变量赋值;镜像编译成功之后,ARG指定的变量不再存在(ENV指定的仍然在镜像中保留)
Docker内置了一些镜像创建变量,用户可以直接使用而无需声明,包括(不区分大小写)HTTP+PROXY HTTPS_PROXY FTP_PROXY NO-PROXY
FROM
指定创建镜像使用的基础镜像
FROM <image> [AS <name>]
或者
FROM <image>:<tag> [AS <name>]
或者
FROM <image>@<digest> [AS <name>]
Dockerfile的第一条命令必须为FROM指令,如果同一个Dockerfile文件创建多个镜像的时候,可以使用多个镜像(每个镜像一次)
LABEL
添加元数据标签信息,用来镜像以后被搜索的时候用
LABEL <key>=<value> <key>=<value> ...
EXPOSE
声明镜像内服务的监听端口,运行容器的时候-P
指令就是根据这个配置来自动映射端口的
EXPOSE <port> [<port>/<protocol>...]
这个指令只是起到声明的作用,并不会自动完成端口映射
ENV
环境变量,容器创建成功仍然存在
ENV <key> <value>
或
ENV <key>=<value> ...
这些环境变量可以在运行时被docker run --env <key>=<value>
覆盖掉
有个需要注意的点,看下这个例子:
ENV key1=value1
ENV key1=value2 key2=${key1}
最后的结果为key1=value2 key2=value1
,因为同一条ENV语句中同时进行赋值
ENTRYPOINT
镜像入口命令,这个命令会在启动容器时作为根命令执行
支持两种结构:
# 这个是在`exec`调用时执行
ENTRYPOINT ["executable","param1","param2"]
# 这个是在`shell`中执行
ENTRYPOINT command param1 param2
所有传入值作为该命令的参数.可以这么理解:你docker run
镜像名后面的字符串,都无脑用空格拼装在这些命令后面
VOLUME
创建一个匿名的数据卷挂载点,可以在运行时被覆盖
VOLUME ["/DATA"]
USER
指定运行容器时的用户名或UID,后续的RUN命令也会使用指定的用户身份
USER daemon
当服务不需要管理员权限时,可以通过该命令指定运行用户
WORKDIR
为后续的RUN
,CMD
,ENTRYPOINT
配置工作目录
WORKDIR /workdir
使用相对指令会和之前的WORKDIR指令进行拼装,所以推荐只使用绝对路径
ONBUILD
基于生成的镜像再次生成子镜像的时候,自动执行的操作命令
其他Dockerfile使用FROM引用生成的镜像的时候会先执行镜像中的ONBUILD语句
ONBUILD [INSTRUCTION]
STOPSIGNAL
指定所创建镜像启动的容器接收退出的信号值:
STOPSIGNAL signal
HEALTHCHECK
配置所启动容器如何进行安全检查
# 禁用镜像安全检查
HEALTHCHECK NONE
# 配置安全检查的命令
HEALTHCHECK [OPTIONS] CMD command
支持的参数有:
- interval=DURATION (default: 30s) 过多久检查一次
- timeout=DURATION (default: 30s) 每次检查等待结果的超时时间
- retries=N (default: 3) 失败后的重试次数
SHELL
指定其他命令使用shell是的默认shell类型
SHELL ["executable","parameters"]
默认值为["/bin/sh","-c"]
操作指令
RUN
运行指定的命令
RUN <command>
或者
RUN ["executable","param1","param2"]
前者默认使用shell终端运行,后者使用exec执行,不启动shell环境
CMD
指定启动容器时默认执行的命令
CMD command param1 param2
或者
CMD ["executable","param1","param2"]
或者
CMD ["param1","param2"] 提供给ENTRYPOINT的默认参数
每个Dockerfile中只能有一条CMD命令,如果指定了多条命令,只有最后一条被执行
如果用户启动容器时手动指定了运行的命令(作为run命令的参数),则会覆盖掉CMD指定的命令
ADD
添加内容到镜像
ADD <src> <dest>
复制src内容到容器内的dest路径
其中src可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar 文件(自动解压为目录);dest可以是镜像内绝对路径,或者相 对于工作目录(WORK.DIR)的相对路径。
COPY
复制内容到镜像
COPY <src> <dest>
src为本地主机Dockerfile所在目录的相对路径;dest为内向内绝对路径,路径不存在的时候,会自动创建
当使用本地目录为源目录时,推荐使用 COPY。
使用Dockerfile创建镜像
编写完Dockerfile以后,通过命令创建镜像
$ docker build [OPTIONS] PATH | URL | -
该命令读取指定路径下的Dockerfile,并将该路径下所有数据作为上下文发送给Docker服务端,Docker服务端在校验Dockerfile格式通过后,逐条执行其中的命令,碰到ADD COPY RUN 指令会生成一层新的镜像,如果最终创建镜像成功,返回最终镜像的ID
如果上下文过大,会发送大量数据到服务端,因此除非是生成镜像必须的文件,不要放在上下文路径;可以使用-f
显式指定上下文路径
用-t
为镜像添加名称,可以多次使用
例如
$ docker build -t builder/first_image :1.0.1 /tmp/docker_builder/
使用.dockerignore
文件
和.gitignore
文件类似,可以在上下文目录添加规则文件,将目录中无用的文件避免提交到服务端
例如
*/temp*
*/*/t
emp*
tmp?
- *是任意个字符
- ?是单个字符
- !是不匹配,即不忽略