Docker
可以通过从Dockerfile
中读取指令来自动构建图像。Dockerfile
是一个文本文档,其中包含用户可以在命令行上调用以组装图像的所有命令。本文介绍了可以在Dockerfile
中使用的命令。
概述
编写Dockerfile
文件来构建Docker
镜像之前,我们需要了解Dockerfile
文件编写支持的命令、关键词具体有哪些,各自有代表什么意思,如下给出一些DockerFile
中的一些指令:
ADD指令
添加本地或远程文件和目录。指令格式如下:
ADD [--chown=<user>:<group>] [--chmod=<perms>] [--checksum=<checksum>] <src>... <dest> #或
ADD [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]
后一种形式对于包含空白的路径是必需的。--chown
和--chmod
功能仅在用于构建Linux
容器的Dockerfiles
上受支持,而在Windows
容器上不起作用。由于用户和组所有权概念不会在Linux
和Windows
之间转换,因此使用/etc/passwd
和/etc/group
将用户和组名称转换为ID会限制此功能仅适用于基于Linux
操作系统的容器。--chmod
从Dockerfile 1.3
开始支持。当前仅支持八进制表示法。
ADD指令从<src>复制新文件、目录或远程文件URL,并将它们添加到路径<dest>的映像文件系统中。可以指定多个<src>资源,但如果它们是文件或目录,则它们的路径将被解释为相对于构建上下文的源。每个<src>都可能包含通配符,并且将使用Go的文件路径进行匹配。匹配规则。例如:
ADD hom* /mydir/ # 要添加所有以“hom”开头的文件:
ARG指令
使用生成时变量。ARG
指令定义了一个变量,用户可以在构建时通过使用--build ARG<varname>=<value>
标志的docker
构建命令将该变量传递给构建器。如果用户指定的构建参数未在Dockerfile
中定义,则该构建会输出警告。格式如下:
ARG <name>[=<default value>]
Dockerfile
可以包括一个或多个ARG
指令。例如,以下是有效的Dockerfile
:
FROM busybox
ARG user1
ARG buildno=1 #ARG指令可以选择性地包括一个默认值:
# ...
CMD指令
指定默认命令。CMD指令设置从映像运行容器时要执行的命令。您可以使用shell或exec形式指定CMD指令:
CMD ["executable","param1","param2"]
CMD ["executable","param1","param2"]
CMD command param1 param2
COPY指令
复制文件和目录。命令格式如下:
COPY [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]
使用功能字面意思就是复制文件,将当前目录下的指定路径文件复制到镜像或容器指定地址。这个命令在使用过程中用的频率较高,示例如下:
PY hom* /mydir/
ENTRYPOINT指令
指定默认可执行文件。ENTRYPOINT允许您配置将作为可执行文件运行的容器。你也可以不配置,它会执行默认的可执行文件。使用格式如下:
ENTRYPOINT ["executable", "param1", "param2"] #或
ENTRYPOINT command param1 param2
ENV指令
设置环境变量。用的比较多,如系统设置运行环境参数,常规的我们的前端项目可能会设置NODE_ENV
区分开发环境。其常用格式如下:
ENV <key>=<value> ...
ENV
指令将环境变量<key>
设置为值<value>
。该值将在构建阶段的所有后续指令的环境中,并且可以在许多指令中内联替换。该值将被解释为其他环境变量,因此如果引号字符没有转义,它们将被删除。与命令行解析一样,引号和反斜杠可以用于在值中包含空格。使用示例如下:
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
ENV指令允许多个<key>=<value>。。。一次设置变量,下面的例子将在最终图像中产生相同的净结果:
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
MY_CAT=fluffy
当从生成的映像运行容器时,使用ENV
设置的环境变量将保持不变。您可以使用docker inspect
查看这些值,并使用docker run--env=
更改它们。
EXPOSE指令
描述您的应用程序正在监听哪些端口。需要注意的是这个只是描述当前应用容器正在监听的端口并不能指定映射的宿主机的端口。使用格式如下:
EXPOSE <port> [<port>/<protocol>...]
EXPOSE指令通知Docker容器在运行时侦听指定的网络端口。您可以指定端口侦听TCP还是UDP,如果未指定协议,则默认为TCP。
EXPOSE指令实际上并没有发布端口。它的作用是构建映像的人和运行容器的人之间的一种文档,说明要发布哪些端口。要在运行容器时发布端口,请在docker运行时使用-p标志来发布和映射一个或多个端口,或者使用-p标志来发布所有公开的端口并将其映射到高阶端口。
EXPOSE 80/udp
FROM指令
从基本映像创建新的构建阶段。即当前构建镜像的依赖镜像,一般多为系统级别的基础镜像信息,使用格式如下:
FROM [--platform=<platform>] <image> [AS <name>] # 或
FROM [--platform=<platform>] <image> [AS <name>] # 或
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
FROM
指令初始化一个新的构建阶段,并为后续指令设置基本映像。因此,有效的Dockerfile
必须以FROM
指令开头。该镜像可以是任何有效的镜像。
ARG
是Dockerfile
中FROM
之前的唯一指令。FROM
可以在单个Dockerfile
中多次出现,以创建多个映像,或者将一个构建阶段用作另一个的依赖项。只需在每条新的FROM
指令之前记下提交输出的最后一个映像ID
即可。每个FROM
指令都会清除先前指令创建的任何状态。- 可选地,可以通过将AS名称添加到FROM指令来为新的构建阶段指定名称。该名称可以在随后的
FROM
和COPY-FROM=
指令中使用,以引用在此阶段构建的镜像。 - 标记值或摘要值是可选的。如果省略其中任何一个,则默认情况下构建器将采用最新的标记。如果生成器找不到标记值,则返回一个错误。
可选的--platform
标志可用于在FROM
引用多平台映像的情况下指定映像的平台。例如,linux/amd64、linux/arm64
或windows/amd64
。默认情况下,将使用构建请求的目标平台。全局构建参数可以用于此标志的值,例如,自动平台ARG允许您将阶段强制到本机构建平台(--platform=$BUILDPORM
),并使用它交叉编译到阶段内的目标平台。
HEALTHCHECK指令
启动时检查容器的运行状况。HEALTHCHECK
指令告诉Docker
如何测试容器以检查它是否仍在工作。这可以检测到一些情况,例如web
服务器陷入无限循环,无法处理新的连接,即使服务器进程仍在运行。格式如下:
HEALTHCHECK [OPTIONS] CMD command #通过在容器内运行命令来检查容器运行状况
HEALTHCHECK NONE # 禁用从基本映像继承的任何健康检查
LABEL指令
向镜像中添加元数据。LABEL指令将元数据添加到图像中。LABEL是一个键值对。若要在LABEL值中包含空格,请像在命令行分析中一样使用引号和反斜杠。一些用法示例:
LABEL <key>=<value> <key>=<value> <key>=<value> ... #格式
#示例
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
MAINTAINER指令
指定镜像的作者信息。MAINTAINER
指令设置生成镜像的“作者”字段。LABEL
指令是一个更灵活的版本,您应该使用它,因为它可以设置您需要的任何元数据,并且可以很容易地查看,例如使用docker inspect
。要设置与MAINTAINER
字段相对应的标签,可以使用:
MAINTAINER <name> # 指令格式
# LABEL 使用
LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"
ONBUILD指令
指定在生成中使用镜像的时间说明。ONBUILD指令向映像中添加一条触发器指令,该指令将在以后映像用作另一个生成的基础时执行。触发器将在下游构建的上下文中执行,就好像它是在下游Dockerfile中的FROM指令之后立即插入的一样。格式如下:
ONBUILD INSTRUCTION
# 示例
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
需要注意的是:
- 不允许使用
ONBUILD-ONBUILD
链接ONBUILD
指令。 ONBUILD
指令可能不会触发FROM
或MAINTAINER
指令。
RUN指令
执行构建命令。RUN指令
将执行任何命令,在当前图像的顶部创建一个新层。添加的层将在Dockerfile
的下一步中使用。
RUN apt-get update
RUN apt-get install -y curl
可以使用shell或exec形式指定RUN指令:
RUN ["executable","param1","param2"] #或
RUN command param1 param2
shell
形式是最常用的,使用换行符或heredocs,可以更容易地将较长的指令分解为多行:
RUN <<EOF
apt-get update
apt-get install -y curl
EOF
SHELL指令
设置镜像的默认执行shell
。SHELL
指令允许覆盖用于命令SHELL
形式的默认SHELL
。Linux
上的默认shell
为[“/bin/sh”,“-c”]
,Windows
上的默认shell为[“cmd”,“/S”,“/c”]
。SHELL
指令必须在Dockerfile
中以JSON
形式编写。
SHELL ["executable", "parameters"] #指令格式
#使用示例
FROM microsoft/windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello
STOPSIGNAL指令
指定退出容器的系统调用信号。STOPSSIGNAL
指令设置将发送到容器以退出的系统调用信号。该信号可以是SIG<name>
格式的信号名称,例如SIGKILL
,也可以是与内核系统调用表中的位置匹配的无符号数字,例如9。如果未定义,则默认值为SIGTERM
。
STOPSIGNAL signal
USER指令
设置用户和组ID。USER指令设置用户名(或UID)和可选的用户组(或GID),用作当前阶段剩余部分的默认用户和组。指定的用户用于执行RUN指令,并在运行时运行相关的ENTRYPOINT和CMD命令。格式如下:
USER <user>[:<group>] # 或者
USER UID[:GID]
#使用配置
FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick
VOLUME指令
设置卷挂载地址。VOLUME
指令使用指定的名称创建一个装载点,并将其标记为容纳来自本机主机或其他容器的外部装载卷。该值可以是JSON
数组,VOLUME[“/var/log/”]
,或带有多个参数的纯字符串,如VOLUME/var/log
或VOLUME/var/log/var/db
。
docker run
命令使用基本映像中指定位置存在的任何数据初始化新创建的卷。例如,考虑以下Dockerfile
片段:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
此Dockerfile
会生成一个映像,该映像使docker run
在/myvol
上创建一个新的装载点,并将问候文件复制到新创建的卷中。
WORKDIR指令
更改工作目录。WORKDIR
指令为Dockerfile
中的任何RUN、CMD、ENTRYPOINT、COPY
和ADD
指令设置工作目录。如果WORKDIR
不存在,即使它没有在任何后续的Dockerfile
指令中使用,它也会被创建。格式如下:
WORKDIR /path/to/workdir
WORKDIR
指令可以在Dockerfile
中多次使用。如果提供了一个相对路径,它将是相对于上一个WORKDIR
指令的路径。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
这个Dockerfile
中的最后一个pwd
命令的输出将是/a/b/c
。
WORKDIR
指令可以解析先前使用ENV
设置的环境变量。只能使用Dockerfile
中显式设置的环境变量。例如:
ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
这个Dockerfile
中最后一个pwd
命令的输出将是/path/$DIRNAME