概述
Dockerfile 是 Docker 中用于构建镜像的文本文件。它包含了一系列的指令和参数,用于定义镜像的基础操作、环境设置和应用程序配置等。通过 Dockerfile,可以自动化地构建、配置和部署 Docker 容器镜像,使得应用程序的部署过程更加可持续、可重复和自动化。
文件一般由四部分组成:
- 基础镜像
- 维护者信息
- 镜像操作指令
- 容器启动执行指令
文件说明
Docker 以从上到下的顺序运行 Dockerfile 指令,以 #
字符开头则被视为注释,可以在文件中使用 RUN
、CMD
、FROM
、EXPOSE
、ENV
等指令。
以 SpringBoot 应用构建为例,一个基本的 Dockerfile 文件内容声明如下:
# Dockerfile with SpringBoot Application
FROM java:8
ARG JAR_FILE
ADD target/${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
指令详解
如下整理 Dockerfile 指令,点击左侧链接可快速跳转至详细说明,更多用法请参考:
Dockerfile 指令 | 说明 |
---|---|
FROM | 指定基础镜像,用于后续的指令构建 |
LABEL | 添加镜像的元数据,使用键值对的形式 |
MAINTAINER 已弃用 | 维护者信息 |
RUN | 在构建过程中在镜像中执行命令 |
CMD | 指定容器创建时的默认命令 |
ENTRYPOINT | 设置容器创建时的主要命令 |
EXPOSE | 声明容器运行时监听的特定网络端口 |
ENV | 在容器内部设置环境变量 |
ADD | 将文件、目录或远程URL复制到镜像中 |
COPY | 将文件或目录复制到镜像中 |
VOLUME | 为容器创建挂载点或声明卷 |
WORKDIR | 设置后续指令的工作目录 |
USER | 指定后续指令的用户上下文 |
ARG | 定义在构建过程中传递给构建器的变量,可使用 docker build 命令设置 |
ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器 |
STOPSIGNAL | 设置发送给容器以退出的系统调用信号 |
HEALTHCHECK | 定义周期性检查容器健康状态的命令 |
SHELL | 覆盖 Docker 中默认的 shell ,用于 RUN 、CMD 和 ENTRYPOINT 指令 |
FROM 指令
FROM
指令用于指定基础镜像,用于后续的指令构建,所以尽可能使用官方镜像,来作为容器的基础环境,有效的 Dockerfile
必须以 FROM
指令开头(用于 FROM
的 ARG
除外)。
AS name
(可选)可以通过添加到指令来为新的构建阶段指定名称,可以用于后续的FROM
或者 `COPY --from``tag
或digest
,如果省略,默认采用latest
标签,如果构建找不到该tag
值,则会返回错误。
用法:
FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
基础示例:
镜像版本查找可通过:https://hub.docker.com/search
# 使用 centos 默认(latest)版本作为基础镜像
FROM centos
# 使用 centos 指定版本(7.9.2009)作为基础镜像
FROM centos:7.9.2009
指定镜像平台示例:
如果引用的是一个多平台镜像,需要交叉编译构建,可以通过
--platform
指定镜像平台,如:linux/amd64
、linux/arm64
或windows/amd64
,如下:
# 使用 centos 默认(latest)版本作为基础镜像,并指定引用镜像平台为 linux/amd64
FROM --platform=linux/amd64 centos
多构建阶段示例:
可以在 Dockerfile 文件中使用多次
FROM
,以创建多个镜像或使用一个构建阶段作为另一个构建阶段的依赖项,每个FROM
之前都会清除由先前指令创建的任何状态:
# 第一阶段构建,基于 Node 环境安装依赖打包应用
FROM node AS node1
LABEL maintainer="do@dodoo.co"
COPY . /app/
WORKDIR /app
RUN npm install
RUN npm build
# 第二阶段,基于 nginx 环境,将打包后静态资源 COPY 至 nginx 默认目录
FROM nginx
COPY --from=node1 /app/dist /usr/share/nginx/html
ARG 和 FROM 如何交互
FROM
指令支持调用由出现在第一个FROM
之前的任何ARG
指令声明的变量。
# 示例:使用 ARG 将变量指定基础镜像版本
ARG VERSION=latest
FROM nginx:${VERSION}
CMD /code/run-nginx
# 在 FROM 之前声明的 ARG 变量,不能在 FROM 之后的任何指令中使用
FROM php:${VERSION}
CMD /code/run-php
若要使用在第一个
FROM
之前声明的ARG
默认值,需要在构建阶段内声明一次没有默认值的ARG
指令,如下:
ARG VERSION=latest
FROM nginx:${VERSION}
# 再次声明没有默认值的 ARG 指令
ARG VERSION
RUN echo $VERSION
RUN 指令
建议
RUN 指令在构建时将会生成一个新的镜像层,并执行 RUN 指令后的内容,为避免创建多个镜像层,建议将多条 RUN 指令进行合并。
用法:
# shell 模式
RUN <command>
# exec 模式
RUN ["executable","param1","param2"]
shell 模式示例:
命令在 shell 中执行:
- Linux 下默认使用:
/bin/sh -c
- Windows 下默认使用:
cmd /S /C
可以将多个命令使用(
&&
)拼接,放在同一个RUN
指令中,也可以使用反斜杠(\
)将复杂RUN
命令换行,如下:
# 加 && 拼接多个命令,加 \ 将长命令进行换行
RUN /'source $HOME/.bashrc && \
echo $HOME'
# 替换为其他 shell ,可显示声明 shell ,以 /bin/bash 为例:
RUN /bin/bash -c echo hello
exec 模式示例:
exec 模式可以避免 shell 字符串修改,参数会被解析为
JSON
数组,因此参数必须使用双引号(""
)包裹,exec 不调用命令 shell,所以不会发生正常的 shell 处理,如下:
# 不会对变量进行替换
RUN ["echo", "$HOME"]
# 想要 shell 处理,则可以使用 shell 形式或直接执行 shell
RUN ["/bin/sh", "-c", "echo $HOME"]
如使用除 /bin/sh
之外的其他 shell
,可做如下替换:
# 替换 /bin/sh 为 /bin/bash
RUN ["/bin/bash","-c","echo hello"]
RUN --mount 指令
允许创建可以访问的文件系统挂载,可以用于:
- 创建主机文件系统或其他构建阶段的绑定挂载
- 访问构建机密或 ssh-agent 套接字
- 使用持久的包管理缓存来加快构建速度
用法:
RUN --mount=[type=<TYPE>][,option=<value>[,option=<value>]...]
支持类型:
更多细节及用法,请参考官方文档:RUN --mount
type | 描述 |
---|---|
bind 默认 | 绑定挂载上下文目录(只读)。 |
cache | 挂载临时目录以及缓存编译器和包管理器的目录。 |
tmpfs | 允许在构建容器中装载 tmpfs 。 |
secret | 允许构建容器访问安全文件(如私钥),而无需将其放入到镜像中。 |
ssh | 允许构建容器通过 SSH 代理访问 SSH 密钥 ,并支持密码短语。 |
RUN --network 指令
允许控制命令运行的网络环境。
用法:
RUN --network=<TYPE>
支持类型:
更多细节及用法,请参考官方文档:RUN --network
type | 描述 |
---|---|
default 默认 | 在默认网络中运行。 |
none | 在没有网络访问的情况下运行。 |
host | 在主机的网络环境中运行。 |
RUN --security 指令
暂未在稳定的 docker 版本中使用
--security=insecure
构建在不安全模式下运行没有沙箱的命令,即允许需要提升权限的流程,相当于执行
docker run --privileged
。
--security=sandbox
默认沙箱模式可以通过
--security=sandbox
激活,但这是无操作的。
CMD 指令
Dockerfile 只能有一个
CMD
指令生效,如果指定多个,则只有最后一个CMD
生效。
CMD
主要目的是为执行容器提供默认值,可以包含可执行文件,也可以省略,省略时必须指定ENTRYPOINT
值。如果使用
CMD
为ENTRYPOINT
指令提供默认参数,则应使用JSON
数组格式指定CMD
和ENTRYPOINT
指令。
用法:
# exec 模式(首选)
CMD ["executable","param1","param2"]
# 作为 ENTRYPOINT 的默认参数
CMD ["param1","param2"]
# shell 模式
CMD command param1 param2
示例:
# 使用 exec 模式
CMD ["/usr/bin/wc","--help"]
# 使用 shell 模式
CMD echo "this is a test." | wc -
LABEL 指令
将元数据添加到镜像中,镜像默认继承基础镜像的标签,如果标签已存在但具有不同的值,则最近应用的值将覆盖任何先前设置的值。
用法:
LABEL <key>=<value> <key>=<value> ...
示例:
LABEL
值使用双引号(""
)包裹,一个镜像可以包含多个LABEL
,可以在一行指定多个LABEL
,也可以通过反斜杠(\
)进行换行:
# 一行指定多个 LABEL
LABEL multi.label1="value1" multi.label2="value2" multi.label3="value3"
LABEL version="1.0.0"
# 使用 \ 进行换行
LABEL description="hello \
world! "
MAINTAINER 指令 已弃用
设置镜像的作者信息,已弃用。
MAINTAINER <name>
推荐使用
LABEL
指令,可以设置你需要的任何元数据。
LABEL org.opencontainers.image.authors="do@dodoo.co"
EXPOSE 指令
声明
Docker
容器在运行时监听指定的端口及协议,如果不指定协议,默认为TCP
。
提示
EXPOSE
指令实际上并未发布端口,仅指定容器提供服务需要用到的端口。
用法:
EXPOSE <port> [<port>/<protocol> ...]
示例:
# 暴露 80 端口,udp 协议
EXPOSE 80/udp
# 如果同时暴露 tcp 和 udp 协议
EXPOSE 80/tcp
EXPOSE 80/udp
ENV 指令
设置环境变量,可用于后续所有指令中,与
LABEL
指令相同,允许设置多个变量。子阶段会继承父阶段或任何祖先阶段的
ENV
设置的环境变量。
用法:
ENV <key>=<value> ...
示例:
# 设置单个变量
ENV CUSTOM_CODE=100
# 设置多个变量(引号:""、反斜杠:\、空格: 可用于变量值中)
ENV CUSTOM_KEY=key CUSTOM_VALUE="value" CUSTOM_PREFIX=Hello\ World\ prefix
# 替代语法(后续版本可能会删除):可以省略等号,省略等号时,不允许一条指令中设置多个环境变量
ENV CUSTOM_KEY key
ADD 指令
从路径复制新文件、目录或远程文件URL <src>
,添加到镜像的文件系统中 <dest>
。
<src>
:可以是Dockerfile
所在目录的一个相对路径(文件或目录),也可以是一个URL
,还可以是一个tar
文件(自动解压为目录)- 可以指定多个
<src>
资源,如果是文件或目录,则路径被解析为相对于构建上下文的源 <dest>
:可以是镜像内绝对路径,或者是工作目录(WORKDIR
)的相对路径- 路径支持通配符,使用
Go
的filepath.Match
来完成匹配规则 --chown
:指定用户、组,仅适用于构建Linux
容器的Dockerfile
上,因为在Windows
系统上没有用户、组的概念--checksum
:远程文件校验和,当前仅支持http
源
ADD 和 COPY 的区别和使用场景
ADD
和 COPY
的区别和使用场景:
ADD
支持添加远程URL
和自动提权压缩格式文件,COPY
只允许从本机中复制文件COPY
支持从其他构建阶段中复制源文件(--from
)- 根据官方
Dockerfile
最佳实践,除非真的需要从远程URL
添加文件或自动提取压缩文件采用ADD
,其他情况一律使用COPY
注意:
ADD
从远程URL
获取文件和复制的效果并不理想,因为该文件会增加Docker Image
最终的大小- 应该使用
CURL
或WGET
来获取远程文件,然后在不需要时进行删除
用法:
ADD [--chown=<user>:<group>] [--chmod=<perms>] [--checksum=<checksum>] <src>... <dest>
# 包含空格的路径需要这种形式
ADD [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]
示例:
# 将以 home 开头的所有文件,添加到 customDir 路径下
ADD home* /customDir/
# 用 ? 替换单个字符,将以 home 开头的 txt 文件,添加到 customDir 路径下
ADD home?.txt /customDir/
# 使用相对路径,将 test.txt 添加到工作目录下的 relativeDir 下
ADD test.txt relativeDir/
# 使用绝对路径,将 test.txt 添加到目录 absoluteDir 下
ADD test.txt /absoluteDir/
# 添加包含特殊字符的文件或目录时,需要遵循 Golang 规则对路径进行转义,防止被解析为匹配模式
ADD arr[[]0].txt /customDir/
# 指定文件目录、组权限
ADD --chown=1 files* /customDir/
ADD --chown=bin files* /customDir/
ADD 遵循原则
<src>
路径必须在构建的上下文中
<src>
是一个URL
<dest>
不以斜杠结尾,那么文件将从URL
下载并复制到<dest>
<dest>
以斜杠结尾,则从URL
推断文件名并将文件下载到<dest>/<filename>
URL
必须有一个重要的路径,以便在如上这种情况下可以找到文件名(http://example.com 将不起作用)
<src> 是目录
- 则会复制目录的全部内容,包括文件系统元数据
- 不会复制目录本身,只会复制其内容
<src>
是压缩格式的本地tar
文件- 会将其自动解压为目录
- 来自远程
URL
资源不会被解压缩 - 当一个目录被复制或解压时,它的行为与
tar -x
相同 - 文件是否被识别为可识别的压缩格式完全取决与文件的内容,而不是文件的名称
<src>
是任何其他类型的文件- 则将其与其元数据一起单独复制
<dest>
以斜杠/
结尾,它将被视为一个目录,并且<src>
的内容将写入<dest>/base(<src>)
- 指定了多个
<src>
资源,或使用了通配符,<dest>
必须是一个目录,并且必须以斜杠/
结尾 <dest>
不以斜杠结尾,它将被视为常规文件,并将<src>
内容写入<dest>
<dest>
不存在,路径中所有缺失的目录都会自动创建<src>
的内容发生变化,第一个遇到的ADD
指令将使来自Dockerfile
的所有后续指令的缓存无效,包括使RUN
指令的缓存无效
COPY 指令
从容器的文件系统中复制新文件或目录将他们添加到路径中
用法:
COPY [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
# 包含空格的路径需要这种形式
COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]
示例:
# 将以 home 开头的所有文件,复制到 customDir 路径下
COPY home* /customDir/
# 用 ? 替换单个字符,将以 home 开头的 txt 文件,复制到 customDir 路径下
COPY home?.txt /customDir/
# 使用相对路径,将 test.txt 复制到工作目录下的 relativeDir 下
COPY test.txt relativeDir/
# 使用绝对路径,将 test.txt 复制到目录 absoluteDir 下
COPY test.txt /absoluteDir/
# 复制包含特殊字符的文件或目录时,需要遵循 Golang 规则对路径进行转义,防止被解析为匹配模式
COPY arr[[]0].txt /customDir/
# 从指定构建阶段 base 寻找源文件 /tmp/example.txt 并复制到 /target/exmaple.txt
FROM ubuntu AS base
COPY --from=base /tmp/example.txt /target/example.txt
COPY 遵循规则
<src>
路径必须在构建的上下文中<src>
是目录- 则复制目录的全部内容,包括文件系统元数据
- 不会复制目录本身,只会复制其内容
<src>
是任何其他类型的文件- 则将其与元数据一起单独复制
<dest>
以斜杠/
结尾,它将被视为一个目录,并且<src>
的内容将写入<dest>/base(<src>)
- 指定了多个
<src>
资源,或者由于使用了通配符,则<dest>
必须是一个目录,并且必须以斜杠/
结尾 <dest>
不以斜杠结尾,将被视为常规文件,并且<src>
的内容将写入<dest>
<dest>
不存在,路径中所有缺失的目录都会自动创建<src>
的内容发生变化,第一个遇到的ADD
指令将使来自Dockerfile
的所有后续指令的缓存无效,包括使RUN
指令的缓存无效
ENTRYPOINT 指令
指定镜像的默认入口命令,该入口命令会在容器启动时作为根命令执行,所有其他传入值作为该命令的参数
可以通过
docker run -entrypoint
来覆盖只有
Dockerfile
中的最后一条ENTRYPOINT
指令会起作用
用法:
当指定了 ENTRYPOINT
后,CMD
的含义就发生了改变,不再是直接的运行其命令,而是将 CMD
的内容作为参数传给 ENTRYPOINT
指令
提示
CMD
和 ENTRYPOINT
命令都定义了容器运行时的运行命令
Dockerfile
必须有一条CMD
或ENTRYPOINT
命令- 如果容器作为可执行程序运行,需要指定
ENTRYPOINT
命令 CMD
命令应该用作定义ENTRYPOINT
命令的默认参数,或在容器启动中执行临时命令的方式- 当
CMD
使用替代参数运行容器时将被覆盖
# exec 格式
ENTRYPOINT ["executable", "param1", "param2"]
# shell 格式
ENTRYPOINT command param1 param2
exec 格式示例:
# 替换 CMD 参数
ENTRYPOINT ["/bin/echo","Hello"]
CMD ["world"] # 表示默认参数,没提供参数,则使用此参数
docker run -it [image] # 输出 Hello world
docker run -it [image] "Docker" # 输出 Hello Docker, 不使用默认参数
docker run -it [image] "James" "Bond" # 输出 Hello James Bond, 使用多个参数
# ENTRYPOINT 设置默认命令参数,使用 CMD 设置可变动参数
ENTRYPOINT ["top","-b"]
CMD ["-c"]
docker run -it [image] -H # 实际执行 top -b -H
shell 格式示例:
ENTRYPOINT exec top -b
VOLUME 指令
创建一个匿名的数据挂载点,运行容器时,可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据等
用法:
VOLUME ["/data"]
示例:
# 用法中的 "/data" 可以是一个 JSON 数组
VOLUME ["/var/log/"]
# 也可以是一个或多个纯字符串
VOLUME /var/log
VOLUME /var/log /var/db
注意事项
- 如果是以
Windows
系统为基础的容器,容器中的目标路径必须是以下两种之一:- 一个不存在的目录或者空目录
- 只能是
C
盘之外的硬盘空间
- 从
Dockerfile
中更改VOLUME
:如果任何构建步骤在声明后更改了VOLUME
内的数据,那么这些更改将被丢弃 - 如果参数是
JSON
数组形式,必须使用双引号(""
)
主机目录(挂载点)在容器运行期间创建:主机目录(挂载点)本质上是与主机相关的,而我们无法保证给定的主机目录在所有主机上都可用,因此为了保持镜像的可移植性,我们不能从 Dockerfile
中挂载主机目录,所以 VOLUME
指令不支持指定 host-dir
参数,只能在创建或运行容器时指定挂载点
USER 指令
指定运行容器时的用户名或 UID
,当容器运行的服务不需要管理员权限时,可以先建立一个特定的用户和用户组,为它分配必要的权限,使用 USER
切换到这个用户
- 使用
USER
指定可以设置用户名(或UID
)以及可选的用户组(或GID
)- 使用
USER
指定用户后,Dockerfile
中后续的命令RUN
、CMD
、ENTRYPOINT
都将使用该用户
用法:
# 指定 用户名、组名
USER <user>[:<group>]
# 指定 用户ID、组ID
USER <UID>[:<GID>]
示例:
# 设置用户名 www
USER www
注意事项
- 在
Windows
上,如果用户不是内置账户,则必须创建该用户 - 可以通过
Dockerfile
的RUN net user
命令来完成,如下:
# 在容器创建新用户
RUN net user /add www
# 设置用户
USER wwww
也可以使用
docker run -u
指定用户- 替代默认设置的用户
- 可以使用
uid
来指定用户
shelldocker run -it -u 1001 busybox sh
WORKDIR 指令
- 切换到镜像中的指定路径,设置工作目录
- 在
WORKDIR
中需要使用绝对路径,如果镜像中对应的路径不存在,会自动创建此目录- 一般用
WORKDIR
来替代RUN cd <path> && <do something>
切换目录进行操作的命令WORKDIR
指令为Dockerfile
中跟随它的任何RUN
、CMD
、ENTRYPOINT
、COPY
、ADD
指令设置工作目录- 如果
WORKDIR
不存在,即使它没有在任何后续Dockerfile
命令中使用,它也会被创建
用法:
WORKDIR /path/to/workdir
示例:
WORKDIR
指令可以在Dockerfile
中多次使用,如果提供了相对路径,它将相对于前一个WORKDIR
指令的路径,为了避免出错,推荐WORKDIR
指令中只使用绝对路径
# 指定工作目录为 /tmp
WORKDIR /tmp
COPY test.txt .
# WORKDIR 指令,可以使用 ENV 设置的环境变量
ENV DIRPATH=/path
WORKDIR DIRNAME
RUN pwd # /path/$DIRNAME
ARG 指令
用于定义一个变量,用户可以在构建 Docker 镜像时,使用
--build-arg
定义变量,如下:新建一个 Dockerfile 文件,使用
ARG
指令定义参数username
,这里没有赋予默认值:dockerfileFROM ubuntu ARG param RUN echo $param
使用构建命令,并传入变量参数:
shelldocker build --build-arg param=helloworld -t myimage:1.0.0.beta .
警告
不建议在构建时使用 ARG
指令传递秘钥、用户凭证等信息,因为构建时的信息任何用户都可以通过 docker history 看到 !!!
用法:
ARG <name>[=<default value>]
示例:
# 如果在 FROM 指令之前指定,那么只能用于 FROM 指令中
ARG VERSION=latest
FROM ubuntu:${VERSION}
# 多阶段构建时,FROM 指令之前定义的 ARG 变量,每个 FROM 都能用
ARG VERSION=latest
FROM ubuntu:${VERSION}
RUN echo 'ubuntu...'
FROM node:${VERSION}
RUN npm -v
提示
ARG
和 ENV
的区别:
ARG
定义的变量只会存在于镜像的构建过程,启动容器后并不保留这些变量ENV
定义的变量在启动容器后仍然保留
预定义ARG
Docker
中有一组预定义的变量,无需Dockerfile
中的ARG
指令指定,在运行容器时通过--build-arg
参数指定即可,而且这些预定义变量不会在docker history
中记录。
预定义变量如下:
HTTP_PROXY
http_proxy
HTTPS_PROXY
https_proxy
FTP_PROXY
ftp_proxy
NO_PROXY
no_proxy
ALL_PROXY
all_proxy
ONBUILD 指令
ONBUILD
是一个特殊的指令,它后面跟着的是其他指令,比如RUN
、COPY
等,而这些指令,在当前镜像构建时并不会被执行,只有当前镜像作为基础镜像,去构建下一级镜像的时候才会被执行。
Dockerfile
中的其它指令都是为了定制当前镜像而准备的,唯有ONBUILD
是为了帮助别人定制自己而准备的
ONBUILD 工作原理
- 当遇到
ONBUILD
指令时,构建器会向正在构建的镜像的元数据添加触发器。没有ONBUILD
指令时,不会影响当前构建。- 构建结束时,所有触发器的列表存储在镜像清单中的
.Container.OnBuild
键中。可以使用命令docker inspect
检查它们。- 使用
FROM
指令将镜像用作新构建的基础镜像时,作为处理FROM
指令的一部分,下游构建器将查找ONBUILD
触发器,并按照注册的顺序执行它们。如果任何一个触发器失败,那么FROM
指令将被中止,从而导致构建失败。如果所有触发器都成功,则FROM
指令将完成,构建将照常继续。- 触发器在执行后从当次构建的镜像中清除,换句话说,它们不是由“孙子”构建继承的。 :::
用法:
ONBUILD <INSTRUCTION>
示例:
# 当被作为基础镜像进行构建时,触发器执行 RUN 指令自动创建 /app/src 目录
ONBUILD RUN mkdir /app/src
提示
- 不允许使用
ONBUILD
指令链接ONBUILD
指令 ONBUILD
指令不能令FROM
或MAINTAINER
指令触发
STOPSIGNAL 指令
设置停止容器所要发送的系统调用信号,所使用的信号必须是内核系统调用表中的合法的值,如:
9
、SIGKILL
。
用法:
默认停止信号是
SIGTERM
,在docker stop
的时候会给容器内PID
为1
的进程发送这个signal
,通过--stop-signal
可以设置自己需要的signal
,主要目的是为了让容器内的应用程序在接收到signal
之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是 10s
。
STOPSIGNAL signal
HEALTHCHECK 指令
用于健康检查,通过
HEALTHCHECK
指令告诉Docker
如何测试容器以检查它是否仍在工作,当镜像指定了HEALTHCHECK
指令后,启动容器时,初始状态会为starting
, 检查通过后会变为healthy
,如果连续失败一定次数后,则会变为unhealthy
选项参数:
OPTIONS | 描述 |
---|---|
--interval=DURATION | 运行检查间隔时间,默认:30s |
--timeout=DURATION | 超时时间,默认:30s |
--start-period=DURATION | 初始化时间,默认:0s |
--start-interval=DURATION | 两次检查时间间隔,默认:5s |
--retries=N | 最大重试次数,默认:3 |
用法:
HEALTHCHECK
返回值:
- 0:成功 - 容器运行状况良好并可供使用
- 1:不健康 - 容器无法正常工作
- 2:保留 - 不使用此退出代码
# 通过容器内运行命令来检查容器运行状况
HEALTHCHECK [OPTIONS] CMD command
# 禁用从基础镜像继承的任何健康检查
HEALTHCHECK NONE
示例:
# 每隔 5min 检查一次,通过 curl 检查 Web 服务是否在正常工作
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1
SHELL 指令
用于设置执行命令所使用的默认
shell
类型
Linux
默认为["/bin/sh","-c"]
Windows
默认使用:["cmd","/S","/C"]
SHELL
指令必须在Dockerfile
中以JSON
格式编写,SHELL
指令可以出现多次,每条SHELL
指令都会覆盖所有先前的SHELL
指令,并影响所有后续指令。
用法:
SHELL ["executable","parameters"]
示例:
# Linux 下,指定 /bin/bash
SHELL ["/bin/bash","-c"]
RUN echo hello
# Windows 下,指定 Powershell
SHELL ["powershell","-command"]
RUN Write-Host hello
# Windows 下,指定 cmd
SHELL ["cmd","/S","/C"]
RUN echo hello