基本结构:
Dockerfile由一行行命令语句组成,并且支持以#开头的注释行
Dockerfile分为四部分:基础镜像信息,维护者信息、镜像操作指令和容器启动时执行的命令
Dockerfile指令说明:
FROM:指定所创建镜像的基础镜像
MAINTAINER:指定维护者信息
RUN:运行命令
CMD:指定容器启动时默认执行的命令
LABEL:指定生成镜像的运数据标签信息
EXPOSE:声明镜像内服务所监听的端口
ENV:指定环境变量
ADD:复制指定的
路径下的内容到容器中的 路径下, 可以为URL,如果为tar文件,会自动加压缩到 路径下 COPY:复制本机的
路径下的内容到容器中的 路径下,一般情况下推荐是用COPY而不是ADD ENTRYPOINT:指定镜像的默认入口
VOLUME:创建数据卷挂载点
USER:指定运行容器时的用户名或者UID
WORKDIR:配置工作目录
ARG:指定镜像内使用的参数(例如版本号信息等)
ONBUILD:配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作命令
STOPSIGNAL:容器退出的信号值
HEALTHCHECK:如何进行健康检查
SHELL:指定使用shell时默认的shell类型
FROM:
执行所创建镜像使用的基础镜像。如果本地不存在,会从配置Registry地址下载,格式为
FROM
或者
FROM:
或者
FROM@
任何Dockerfile中的第一条指令必须为FROM指令。如果同一个Dockerfile创建多个镜像,可以使用多个FROM指令
MAINTAINER:
指定维护者信息,格式为MAINTAINER
MAINTAINER [email protected]
改信息会写入生成镜像的Author属性域中
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/cache/apt
CMD:
CMD指令用来指定启动容器时默认执行的命令,它支持三种方式:
CMD ["executable", "param1", "param2"]使用exec执行,是推荐使用的方式
CMD command param1 param2 在/bin/sh中执行,提供给需要交互的应用
CDM [“param1”, "paam2"]提供给ENTRYPOINT的默认参数
每个Dockerfile只能有一条CMD命令,如果指定了多条命令,只有最后一条会被执行,如果启动容器时手动指定了运行的命令(作为run的参数),则会覆盖掉CMD指令的命令
LABEL:
LABEL指令用来指定生成镜像的元数据标签信息
格式为
LABEL= = = ...
例如:
LABEL version="1.0" LABEL description="This text illustrates \ that lable-values can span multiple lines."
EXPOSE:
声明镜像内服务所监听的端口
格式为
EXPOSE[ ...]
例如:
EXPOSE 22 80 8443
注意:改指令只是起到声明作用,并不会完成端口映射。
在启动容器时使用-P,Docker会随机分配一个端口,转发到指定的端口,如果使用-p,则可以具体映射到宿主机本机的某个指定端口上。
ENV:
指定环境变量,在镜像生成过程中被后续的RUN指令所使用,在镜像启动的容器中也会存在。
格式为
ENV
或者
ENV= ...
例如:
ENV PG_MAJOR 9.3 ENV PG_VERSION 9.3.4 RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress &&... ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
指令指定的环境变量在运行时可以被覆盖掉,如
docker run --env= built_image
ADD:
改命令将复制指定的
格式为
ADD
其中
还可以是一个tar文件(如果为tar文件,会自动加压缩到
路径正则格式,如:
ADD *.c /code/
COPY:
格式为
COPY
复制本地主机的
当使用本地目录为源目录时,推荐使用COPY
ENTRYPOINT:
指定镜像的默认入口命令,改入口命令会在容器启动时作为根命令执行,所有传入值作为该命令的参数
支持两种格式:
ENTRYPOINT ["EXECUTABLE", "param1" "param2"](exec调用执行)
ENTRYPOINT command param1 param2(shell中执行)
此时,CMD指令指定值将作为根命令的参数
每个Dockerfile中只能有一个ENTRYPOINT,指定多个时,只有最后一个有效。(这点和CMD指令一样的)
在运行时,可以被--entrypoint参数覆盖掉,如docker run --entrypoint
VOLUME:
创建一个数据卷挂载点
格式为
VOLUME ["/data"]
可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保存的数据等。
USER:
指定运行容器时的用户名或者UID,后续的RUN等指令也会使用指定的用户身份
格式为
USER daemon
当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在之前创建所需要的用户,例如:
RUN groupadd -r postgres && useradd -r -g postgres
要临时获取管理员权限可以使用gosu或者sudo
WORKDIR:
为后续的RUN、CMD和ENTRYOINT指令配置工作目录
格式为
WORKDIR /path/to/workdir
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
最终路径为/a/b/c
ARG:
指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行docker build命令时才以 --build-arg
格式为
ARG[= ]
则可以使用
docker build --build-arg=
来指定参数值
ONBUILD:
配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令。
格式为
ONBUILD [INSTRUCTION]
例如:Dockerfile使用如下的内容创建了镜像image-A;
[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src [...]
如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令
FROM image-A #Automatically run the following ADD . /app/src RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的镜像,推荐在标签中注明,例如:ruby:1.9-onbuild
STOPSIGNAL:
指定所创建的镜像启动的容器接收退出的信号值
STOPSIGNAL signal
HEALTHECK
配置所启动的容器如何进行健康检查,格式有两种:
HEALTHCHECK [OPTIONS] CMD command:根据所执行命令返回值是否为0来判断 HEALTHCHECK NONE:禁止基础镜像中的健康检查
OPTION支持:
--interval=DURATION(默认为:30s):过多久检查一次 --timeout=DURATION(默认为:30s):每次检查等待结果的超时 --retries=N(默认为:3):如果失败了,重试几次才最终确定失败
SHELL:
执行其他命令使用shell时的默认shell类型
SHELL ["executable", "parameters"]
默认值为["/bin/sh", "-c"]
docker build创建镜像
基本格式为
docker build [选项] 内容路径
该命令将读取指定路径下(包括子目录)的dockerfile,并将改路径下的所有内容发送给Docker服务端,由服务端来创建镜像。
因此除非生成镜像需要,否则一般建议放置Dockerfile的目录为空目录。有两点经验:
如果使用非内容路径下的Dockerfile,可以使用-f选项来指定其路径
要指定生成镜像的的标签信息,可以使用-t选项
例如:指定Dockerfile所在路径为/tmp/docker_builder/,并且希望生成镜像标签为build_repo/first_image,可以使用下面的命令
docker build -t build_repo/first_image /tmp/docker_builder/
Docker Hub 上的Dockerfile样例
https://hub.docker.com/search/?isAutomated=0&isOfficial=0&page=1&pullCount=0&q=Dockerfile&starCount=0
例如:
使用.dockerignore文件
.dockerignore
用来忽略上下文目录中包含的一些image用不到的文件,它们不会传送到docker daemon。规则使用go语言的匹配语法。如:
# cat .dockerignore *.rpm tmp*
这会将上下文目录下所有.rpm和tmp.*的文件排除掉
例如:
# cat Dockerfile FROM centos:6 MAINTAINER zengcp WORKDIR /srv #RUN yum -y install vim wget LABEL version="1.0" EXPOSE 22 80 ENV JDK_VERSION 1.8 #COPY ./jdk-8u151-linux-x64.rpm /srv/ copy . ./ VOLUME "/data"
# ls aaa.temp Dockerfile jdk-8u151-linux-x64.rpm temp tmpaaa
这里会将jdk的rpm包和tmpaaa文件排除