Dockerfile使用基本的基于DSL(Domain Specific Language)语法的指令来构建一个Docker镜像。
FROM
FROM一定是第一条指令,用来指定一个基准镜像。如果不想使用基准镜像,那么可以使用scratch
,它是一个虚拟镜像,表示一个空白的镜像
FROM <registry>:<tag>
RUN
RUN指令用来在容器构建过程中运行一个命令。
RUN <command>
RUN ["<executable>","<param1>","<param2>"]
# 在第一个方式中,command通常是一个shell命令,以`/bin/sh -c`的方式运行。
每个RUN指令都会生成一层文件系统,所以常规的做法是将多个命令在一个RUN指令中执行
RUN ["/bin/bash","-c","apt-get update && apt-get install -y redis-server"]
EXPOSE
EXPOSE指令用来设置对外的端口。
EXPOSE <port>[/protocol]
其中protocol是指协议,值为tcp或udp,默认为tcp。多个端口以空格分隔可以同时暴漏多个端口。
CMD
CMD指令用于指定一个容器启动时要运行的命令。
CMD ["/bin/bash"]
CMD ["/bin/bash","-c","apt update"] // 指定参数
使用docker run
命令可以覆盖CMD命令,如果我们在Dockerfile中指定了CMD命令,而同时在docker run命令行中也指定了要运行的命令,命令行中指定的命令会覆盖Dockerfile中的命令。
在Dockerfile中只能指定一条CMD命令,如果指定了多条CMD命令,也只有最后一条指令会被执行。如果想在启动容器时运行多个进程或者多条命令,可以考虑使用类似Supervisor这样的服务管理工具。
ENTRYPOINT
ENTRYPOINT指令也用于指定一个容器启动时要运行的命令。
ENTRYPOINT ["/usr/sbin/nginx"]
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"] // 指定参数
ENTRYPOINT指令与CMD指令非常类似,但ENTRYPOINT指令提供的命令不会被docker run命令行中提供的指令覆盖,docker run命令行中指定的任何参数都会被当做参数再次传递给ENTRYPOINT指令中指定的命令。
如果确实需要,可以在运行时通过docker run
中的--entrypoint
标志覆盖ENTRYPOINT指令。
WORKDIR
WORKDIR指令用来在从镜像创建一个新容器时,在容器内部设置一个工作目录,ENTRYPOINT和CMD指定的程序会在这个目录下执行。也可以为最终的容器设置工作目录。
ENV
ENV指令用来在镜像构建过程中设置环境变量
ENV RVM_PATH /home/rvm
这个新的环境变量可以在后续的任何RUN指令中使用。这些环境变量会被持久的保存到从我们的镜像创建的任何容器中。
在使用docker run
运行时可以通过-e
标志来传递环境变量,值当次有效。
USER
USER指令用来指定该镜像会以什么样的用户去运行。默认用户为root
。
在使用docker run
运行时可以通过-u
标志来覆盖USER指令的值。
VOLUME
VOLUME指令用来向基于镜像创建的容器添加卷。一个卷时可以存在于一个或者多个容器内的特定的目录,这个目录可以绕过联合文件系统,并提供如下共享数据或者对数据进行持久化的功能。
- 卷可以在容器间共享和重用。
- 一个容器不必和其他容器共享卷。
- 对卷的修改是立即生效的。
- 对卷的修改不会对更新镜像产生影响。
- 卷会一直存在直到没有任何容器再使用它。
卷可以让我们将数据(如源代码,应用程序)、数据库、日志或者其他内容添加到镜像中而不是将这些内容提交到镜像中,并且允许我们在多个容器间共享这些内容。
VOLUME ["/data/project"]
VOLUME ["/data/project","/data/logs"]
ADD
ADD指令用来将构建环境下的文件和目录复制到镜像中。比如我们在使用nginx构建静态网站时需要更新配置文件nginx.conf
ADD nginx.conf /etc/nginx/
ADD admin.docker.com.conf /etc/nginx/conf.d/
在ADD文件时,docker通过目的地址参数末尾的字符来判断是目录还是文件。如果目标地址以/
结尾,那么docker就认为目标地址指向目录,如果不以/
结尾,那么docker就认为目标地址指向的是文件。
文件源也可以使用URL的格式:
ADD http://wordpress.org/latest.zip /data/wordpress.zip
如果将一个压缩文件(gzip,bzip2,xz)指定为源文件,docker会自动将压缩文件解压。
ADD latest.tar.gz /home/www/wordpress
上述命令会将压缩文件latest.tar.gz解压到/home/www/workpress目录下。docker解压文件的行为和使用带-x选项的tar命令一样。
如果目的位置的目录下存在同名的目录和文件,那么目的位置中的目录和文件不会被覆盖。如果目的位置不存在,docker将会自动创建全路径,将创建的文件和目录权限为0755。
ADD指令会使缓存变得无效
COPY
COPY指令非常类似与ADD,它们根本的不同是COPY只关心在构建上下文中复制本地文件,而不会去做文件提取和解压。
COPY conf.d/ /etc/apache/
文件源路径必须是一个与当前构建环境相对的文件或者目录,本地文件都会放到和Dockerfile同一个目录下。不能复制该目录之外的任何文件,因为构建环境将会上传到Docker守护进程,而复制是发生在守护进程中,任何位于构建环境之外的东西都是不可用的。目的位置必须是一个容器内部的绝对路径。
LABEL
LABEL指令用于为Docker镜像添加元数据。元数据以键值对的形式展现。可以在一个命令中添加多个键值对,以空格分隔。可以通过docker inspect
命令查看镜像中的标签信息。
LABEL author="liumurong" version="1.0.0"
STOPSIGNAL
STOPSIGNAL指令用来设置停止容器时发送什么系统调用信号给容器。这个信号必须时内核系统调用表中合法的值。
ARG
ARG指令用来定义可以在docker build
命令运行时传递给构建运行时的变量,我们只需要在构建时使用--build-arg
标志即可。用户只能在构建时指定在Dockerfile中定义过的参数。
#添加指令
ARG build
ARG webapp_user=user
#使用指令
docker build --build-arg build=1111 -t "imagename"
参数build将会被设置为1111,webapp_user将会继承默认值user
Docker预定义了一组ARG变量,可以在构建时直接使用。
- HTTP_PROXY
- HTTPS_PROXY
- FTP_PROXY
- NO_PROXY
- http_proxy
- https_proxy
- ftp_proxy
- no_proxy
ONBUILD
ONBUILD指令可以为镜像添加触发器。当一个镜像被用作其他镜像的基础镜像时,该镜像中的触发器会被执行。
触发器会在构建过程中插入新指令,我们可以认为这些指令是紧跟在FROM之后执行的。触发器可以是任何构建指令:
ONBUILD ADD . /home/www
当有镜像基于此镜像构建时,新的镜像会使用ADD指令将构建环境所在的目录下的全部内容添加到镜像中的/home/www目录下。我们可以使用这个镜像作为通用的静态Web应用的基准镜像。
ONBUILD触发器会按照在父镜像中指定的顺序执行,并且只能被继承一次,也就是说只能在子镜像中执行,而不会在孙子镜像中执行。
FROM,MAINTAINER,ONBUILD指令不能用在ONBUILD中,防止递归调用。