Dockerfile文件常用指令详解

镜像的定制实际上就是定制每一层所添加的配置、文件。我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,这个脚本就是Dockerfile。Dockerfile是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

FROM指令

该指令指定基础镜像,然后对镜像进行定制。

FROM ubuntu:16.04

Docker还存在一个特殊的镜像,名为scratch,它表示一个空白镜像,如果你一scratch为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像的第一层。对于Linux下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接FROM scratch会让镜像体积更加小巧。

示例:

FROM scratch

....

RUN指令

RUN指令是用来执行命令行命令的。其格式有两种:

shell格式:RUN <命令>

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

exec格式: RUN ["可执行文件", "参数1", "参数2"]

RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install

COPY指令

复制文件指令,格式如下:

COPY <源路径> <容器内目标路径>

## 示例
COPY a.txt /usr/text/

## 多个源文件
COPY a.txt b.txt /usr/text/

## 通配符形式
COPY hom* /mydir/
COPY hom?.txt /mydir/

ADD指令

ADD和COPY的格式和性质基本一致。但是在COPY基础上增加了一些功能。比如<源路径>可以是一个URL,这种情况下,Docker引擎会试图去下载这个链接的文件放到<目标路径>去。

ADD适合需要自动解压缩的场合,因此可以遵循这样的原则,所有的文件复制均使用COPY指令,仅在需要自动解压缩的场合使用ADD。

CMD指令

就是用于指定容器主进程默认启动命令的。格式如下:

shell格式:CMD <命令>

exec格式: CMD ["参数1","参数2", ...]

参数列表格式:CMD ["参数1","参数2", ...]。在指定了ENTRYPOINT指定后,用CMD指定具体的参数。

ENTRYPOINT指令

ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。ENTRYPOINT在运行时也可以替代,不过比CMD要略显繁琐,需要通过docker run 的参数 --entrypoint来指定。当指定了ENTRYPOINT后,CMD的含义就发生了改变,不再是直接的运行其命令,而是将CMD的内容作为参数传给ENTRYPOINT指令。

ENV指令

该指令用于设置环境变量,格式有两种:

ENV

ENV ==

这个指令很简单,就是设置环境变量而已,无论是后面的其他指令,如RUN,还是运行时的应用,都可以直接使用这里定义的环境变量。

ENV VERSION=1.0 DEBUG=on NAME="Leisure"
$VERSION # 使用环境变量

下列指令可以支持环境变量:ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD

ARG指令

ARG指令用于构建参数,和ENV的效果一样,都是设置环境变量。格式如下:

ARG <参数名>[=<默认值>]

和ENV不同的是,ARG所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用ARG保存密码之类的信息,因为docker history还是可以看到所有值的。

Dockerfile中的ARG指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令docker build中用--build-arg <参数名>=<值>来覆盖

VOLUME指令

该指令用于定义匿名卷,格式为:

VOLUME ["<路径1>","<路径2>", ...]

VOLUME <路径>

VOLUME /data

运行时可以覆盖这个挂载设置:

docker run -d -v mydata:/data mysql:5.7

在这行命令中,就使用了mydata这个命名卷挂载到了/data这个位置,替代了Dockerfile中定义的匿名卷的挂载配置。

EXPOSE指令

该指令用于声明端口,格式为:

EXPOSE <端口1> [<端口2> ...]

EXPOSE指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。

声明端口的好处:

1)帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;

2)在运行时使用随机端口映射时,也就是docker run -P时,会自动随机映射EXPOSE的端口。

WORKDIR指令

该指令用于指定工作目录,格式为:

WORKDIR <工作目录路径>

使用WORKDIR指令可以来指定工作目录(或称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR会帮你建立目录。

初学者可能把Dockerfile等同于Shell脚本来书写,这种错误理解还可能会导致初心下面这样的错误:

RUN cd /app
RUN echo "hello" > world.txt

如果将这个Dockerfile进行构建镜像运行后,会发现找不到/app/world.txt文件。

USER指令

该指令用于指定当前用户,格式为

USER <用户名>

USER指令和WORKDIR相似,都是改变环境状态并影响以后的层。USER只是帮你切换到指定用户,这个用户必须是事先建立好的,否则无法切换。

ONBUILD指令

ONBUILD是一个特殊的指令,它后面跟的是其他指令,比如RUN,COPY等,而这些指令,在当前镜像构件时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。Dockerfile中的其他指令都是为了定制当前镜像而准备的,唯有ONBUILD是为了帮助别人定制自己而准备的。

MAINTAINER指令

用于指定作者,格式为:

MAINTAINER

MAINTAINER leisure <leisure.wang>

原文地址:http://leisure.wang/?p=124