Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像。
指令 | 说明 |
---|---|
ARG | 定义创建镜像过程中使用的变量 |
FROM | 指定所创建镜像的基础镜像 |
LABEL | 为 生成的镜像添加元数据标签信息 |
EXPOSE | 声明镜像内服务监听的端口 |
ENV | 指定环境变量 |
ENTRYPOINT | 指定镜像的默认入口命令 |
VOLUME | 创建一个数据卷挂载点 |
USER | 指定运行容器时的用户名或UID |
WORKDIR | 配置工作目录 |
ONBUILD | 创建子镜像时指定自动执行的操作指令 |
STOPSIGNAL | 指定退出的信号值 |
HEALTHCHECK | 配置所启动容器如何进行健康检查 |
SHELL | 指定默认shell类型 |
RUN | 运行指定命令 |
CMD | 启动容器时指定默认执行的命令 |
ADD | 添加内容到镜像 |
COPY | 复制内容到镜像 |
ARG
格式为ARG [=]。
当镜像编译成功后,ARG指定的变量将不再存在(ENV指定的变量将在镜像中保留。)
Docker内置了一些镜像创建变量,用户可以直接使用而无须声明,包括HTTP_PROXY,HTTPS_PROXY,FTP_PROXY,NO_PROXU。
FROM
格式为FROM [ AS ]或FROM
: [ AS ]或FROM
@ [ AS ]
任何Dockerfile中的第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个竟像时,可以使用多个FROM指令。
LABEL
为生成的镜像添加元数据标签,这些可以辅助过滤出特定镜像。
格式为LABEL =
例如:
LABEL author=“xxxxxx”
EXPOSE
格式为EXPOSE [/]
例如:
EXPOSE 22 80 443
该指令只是起到声明作用,并不会自动完成端口映射。
ENV
格式为 ENV 或 ENV =
例如:
ENV APP_VERSION=1.0.0
ENV PATH $PATH:/usr/local/bin
ENTRYPOINT
指定镜像的默认入口命令,该入口命令会在启动容器时作为跟命令来执行,所有传入值作为该命令的参数。
支持两种格式:
ENTRYPOINT [“executable”,“param1”,“param2”] :exec调用执行。
ENTRYPOINT command param1 param2: shell执行
此时,CMD指令指定值将作为跟命令参数
每个Dockerfile中只能由一个ENTRYPOINT,当指定多个时,只有最有一个起效。
VOLUME
创建一个数据挂载点
格式为VALUME ["/data"]
运行容器时可以从本地主机或其他容器挂载数据卷。
USER
格式为 USER daemon
当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在Dockerfile中创建所需要的用户。例如:
RUN groupadd -r postgres && useradd --no-log-init -r -g postgres postgres
要临时获取管理员权限可以使用gosu命令
WORKDIR
配置工作目录
格式 WORKDIR /path/to/workdir
可以使用多个WORKDIR指令,后续命令如果参数时相对路径,则会基于之前命令指令的路径。
例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
最终路径为 /a/b/c
因此,为了避免出错,推荐WORKDIR使用绝对路径
ONBUILD
配置当所创建的镜像作为其他镜像的基础镜像的时候,所执行创建操作指令。
格式为:ONBUILD [INSTRUCTION]。
例如Dockerfile使用如下的内容创建父镜像ParentImage,指定ONBUILD指令:
#Dockerfile for ParentImage
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于ParentImage镜像创建新的镜像时,新的Dockerfile中使用FROM ParentImage指定基础镜像,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令:
# Automatically run the following
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
由于ONBUILD是隐式执行的,推荐在使用它的标签中进行标注,例如ruby:2.1-onbuild
STOPSIGNAL
指定所创建镜像启动的容器接收退出的信号值。例如:
STOPSIGNAL singnal
HEALTHCHECK
配置所启动容器如何进行健康检查(如何判断是否健康),自Docker 1.12开始支持。
格式有两种:
1.HEALTHCHECK [OPTIONS] CMD command :根据所执行命令返回值是否为0判断;
2.HEALTHCHECK NONE :禁止基础镜像中的健康检查。
[OPTION]支持如下参数:
--inerval=DURATION (默认为:30s):多久检查一次;
--timeout=DURATION (默认为:30s):每次检查等待结果的超时时间;
--retries=N (默认为:3):如果失败了,重试几次才最终确定失败。
SEHELL指定其他命令使用shell时的默认shell类型。
格式为: SHELL [“executable”,“parameters”]
默认值为 [“bin/sh”,"-c"]。
注意:
对于Windows系统,Shell路径中使用了""作为分隔符,建议在Dockerfile开头添加# escape=`来指定转义符。
RUN 运行指定命令。
格式为:RUN或RUN [“executable”,“param1”,“param2”]。
注意:
后一个指令会被解析为json数组,所以必须使用双引号。
前者默认将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。
指定使用其他终端类型可以通过第二种方式实现,例如:
RUN ["/bin/bash","-c",“echo hello”]
每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\换行。例如:
RUN apt-get update \
&& apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \
&& rm -rf /var/lib/apt/lists/*
CMD
CMD指令用来指定启动容器时默认执行的命令。它支持三种格式:
1.CMD ["executable","param1","param2"] 使用exec执行,是推荐使用的方式;
2.CMD param1 param2 在/bin/sh中执行,提供给需要交互的应用;
3.CMD ["param1","param2"] 提供给ENTRYPOINT的默认参数。
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。入股用户启动容器时指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。
ADD该指令将复制指定的路径下的内容到容器中的路径下。
格式为:ADD
其中可以使Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是一个tar文件(如果是tar文件,会自动解压到路径下)。可以使镜像内的绝对路径,或者相当于工作目录(WORKDIR)的相对路径。路径支持正则表达式,例如:
ADD *.c /code/
COPY
复制本地主机的(为Dockerfile所在目录的一个相对路径、文件或目录)下的内容到镜像中的下。目标路径不存在时,会自动创建。路径同样支持正则。
格式为:COPY
当使用本地目录为源目录时,推荐使用COPY。
编写完成 Docker企le 之后,可以通过 docker [image] build 命令来创建镜像 。
基本的格式为 docker build [OPTIONS] PATH | URL I - 。
该命令将读取指定路径下(包括子目录)的 Dock巳rfile ,并将该路径下所有数据作为上下文( Context)发送给 Docker 服务端 。 Docker 服务端在校验 Dockerfile 格式通过后,逐条执行其中定义的指令,碰到 ADD 、 COPY 和 RUN 指令会生成一层新的镜像。 最终如果创建镜像成功,会返回最终镜像的 ID 。
如果上下文过大, 会导致发送大量数据给服务端,延缓创建过程 。 因此除非是生成镜像所必需的文件,不然不要放到上下文路径下 。 如果使用非上下文路径下的 Dockerfile ,可以通过 -f 选项来指定其路径 。
要指定生成镜像的标签信息,可以通过 - t 选项 。 该选项可以重复使用多次为镜像一次添加多个名称 。
例如,上下文路径为/tmp/docker_builder/,并且希望生成镜像标签为 builder/first_image:1.0.0,可以使用下面的命令 :
docker build -t builder/first_image:l.0.0 /tmp/docker_builder/
大部分情况下,生成新的镜像都需要通过 FROM 指令来指定父镜像。 父镜像是生成镜像的基础 ,会直接影响到所生成镜像的大小和功能 。用户可 以选择两种镜像作为父镜像,一种是所谓的基础镜像( baseimage),另外一种是普通的镜像(往往由第三方创建,基于基础镜像) 。
基础镜像 比较特殊,其 Dockerfile 中往往不存在 FROM 指令,或者基于 scratch 镜像(FROM scratch ),这意味着其在整个镜像树中处于根的位置 。
下面的 Dockerfile 定义了一个简单的基础镜像,将用户提前编译好的二进制可执行文件binary 复制到镜像中,运行容器时执行 binary 命令:
FROM scratch
ADD binary /
CMD ["binary "]
普通镜像也可以作为父镜像来使用, 包括常见的 busybox 、 debian 、 ubuntu 等
可 以通过 .dockerignore 文件(每一行添加一条匹配模式)来让 Docker 忽略匹配路径或文件,在创建镜像时候不将无关数据发送到服务端。
例如下面的例子中包括了 6 行忽略的模式(第一行为注释):
/temp
//temp*
tmp?
-*
Dockerfile
!README.md
自17.05版本开始,Docker支持多步骤创建(Multi-stage build)特性,可以精简最终生成的镜像大小。
对于需要编译的应用(如 C、Go或Java语言等)来说,通常情况下至少需要准备两个环境的Docker镜像:
使用多步骤创建,可以保证最终生成的运行环境镜像保持精简的情况下,使用单一的Dockerfile,降低维护复杂度。
以Go语言应用为例。创建干净目录,进入到目录中,创建main.go文件,内容为:
//main.go will output "hello,Docker"
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello,Docker")
}
闯进Dockerfile,使用golang:1.9镜像编译应用二进制文件为app,使用精简的镜像alpine:latest作为运行环境。Dockerfile完整内容为:
FROM golang:1.9 as builder # defin stage name as builder
RUN mkdir -p /go/src/test
WORKDIR /go/src/test
COPY main.go .
RUN CGO_ENABLED=0 GOOS=linux go build -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/test/app . #copy file from the builder stage
CMD ["./app"]
执行如下命令创建容器
[root@study ~ 20:13:39]# docker build -t yeasy/test-multistage:latest .
Sending build context to Docker daemon 470.8MB
Step 1/10 : FROM golang:1.9 as builder
---> ef89ef5c42a9
Step 2/10 : RUN mkdir -p /go/src/test
---> Using cache
---> 66feda4edc16
Step 3/10 : WORKDIR /go/src/test
---> Using cache
---> 5945c2d35d88
Step 4/10 : COPY main.go .
---> Using cache
---> 0fc82e8f2861
Step 5/10 : RUN CGO_ENABLED=0 GOOS=linux go build -o app .
---> Using cache
---> a7afbb419a38
Step 6/10 : FROM alpine:latest
---> 961769676411
Step 7/10 : WORKDIR /root/
---> Using cache
---> 396b73284595
Step 8/10 : RUN apk --no-cache add ca-certificates
---> Using cache
---> dfd7ebe9441f
Step 9/10 : COPY --from=builder /go/src/test/app .
---> Using cache
---> 7b724eed6dfa
Step 10/10 : CMD ["./app"]
---> Using cache
---> a9363c670d62
Successfully built a9363c670d62
Successfully tagged yeasy/test-multistage:latest
[root@study ~ 20:15:06]# docker images | grep "yeasy/test-multistage"
yeasy/test-multistage latest a9363c670d62 About a minute ago 7.99MB
[root@study ~ 20:15:10]# docker run --rm yeasy/test-multistage
Hello,Docker