An article takes you through Dockerfile

introduction

When we first started using Docker, we pulled images directly from Docker's official image warehouse, then created containers based on these images and ran

In fact, the official Docker image is also constructed in a certain way. If we can figure out the construction logic, we can also follow the construction process of the official image to build the image we want.

Dockerfile is such a text file used to describe the process of building a Docker image. This file can contain multiple build instructions and related descriptions

Therefore, before building a custom Docker image, it is necessary to understand the principle of image construction and the relevant syntax of the Dockerfile in order to write an efficient Dockerfile, so as to shorten the overall construction time and reduce the size of the final image

1. Mirror construction principle

(1) Review of Docker Architecture Patterns

As shown in the figure, Docker uses  the client/server  architectural pattern. When building a mirror image, the user enters a build command in the Docker Client , and the Docker engine sends a build request to the Docker daemon  in the form of a REST API , and then the Docker daemon starts the image build work according to the content of the build request, and continuously returns the build to the Client Process information, allowing users to see the current build status

(2) Mirror layered model 

A Docker image is a read-only template used to create a container. It is built through the instructions defined in the Dockerfile. After the build is complete, a new image layer will be generated on the original image layer, as shown in the following figure

Create a container with the tomcat image, and create a writable container layer on top of the tomcat image. When writing files in the container, they will be saved in this container layer, as shown in the following figure

(3) Base image and parent image

The Dockerfile used to build the base image does not specify a parent image, and the Docker convention uses the following form to define the base image

FROM scratch

The scratch here is an empty image, which can be used to build a mirror from scratch. It is often used to build a minimal image, such as busybox, debian, alpine and other images, which saves a lot of Linux commands, so the image is very small. In general, you don't need to build the base image yourself

When building a custom image, specify what parent image to use through FROM. Generally speaking, the official tomcat command does not have yum, vim and other commands. You can use the tomcat image as the parent image, then install yum, vim commands, and then build a custom image, so that these commands can be used directly in the container. As shown below

(4) Build context / build context

The build request sent by the Client to the Docker daemon contains two parts, the first part is the most important Dockerfile , and the second part is the build context

The build context is a collection of files, which can be files under the specified path, or files under the specified path in remote resources. During the build process, the Docker daemon can access these files and perform corresponding operations

The construction context can be divided into the following three situations

1. Path context

The specific path is specified in the build command, all files under this path are the build context, these files will be packaged and sent to the Docker daemon, and then decompressed

Suppose a project file structure is as follows

demo
├── Dockerfile
├── src
├── test
└── node_modules

 Execute the following build command in the project root directory

docker build -t img-tag .

The first part of the build request is the Dockerfile, which is in the current directory, and the file name is the default name, so it can be omitted

It is equivalent to adding -t Dockerfile by default , and the content of Dockerfile is as follows

# syntax=docker/dockerfile:1
FROM busybox
WORKDIR /src
COPY src .

The second part of the build request is .  This point represents the current directory. At this time, the current directory is the construction context of this time. The Docker engine will organize all the files in this directory and  send all the files that are not matched by the rules in .dockerignore Go to the Docker daemon, as shown in the figure below

If you are in the upper directory of the project root directory at this time, the build command is as follows

docker build -t img-tag -f ./demo/Dockerfile ./demo/

2. URL context

Docker also supports building images using remote warehouse URLs, and the specified remote warehouse directory acts as the build context

docker build https://gitee.com:user/my-repo.git#master:docker

The above build command specifies the master branch of a Gitee project. Before the colon (:) is the target URL checked out by Git. After the colon, docker is a subdirectory under the root directory of the remote warehouse. At this time, this subdirectory is the build context

When the Docker client executes the build command, the Docker engine will first pull the master branch of the remote warehouse into a local temporary directory, and then send the files in the docker directory as the build context to the Docker daemon. After pulling the remote file, it returns to the step of the path context, as shown in the figure below

3. Omit context

If the instructions in the Dockerfile do not need to operate on any files, the build context can be omitted, and no additional files will be sent to the Docker daemon, which can improve the build speed

An example build command is as follows

docker build -t my-hello-world:latest -<<EOF
FROM busybox
RUN echo "hello world"
EOF

(5) Build cache

During the iteration process, the resources corresponding to the Dockerfile will be frequently modified, so the image needs to be rebuilt frequently. In order to improve the build speed, Docker has designed a variety of optimization solutions, the most important of which is the build cache

The following will use an example to illustrate how the build cache works, the Dockerfile is as follows

# syntax=docker/dockerfile:1
FROM ubuntu:latest

RUN apt-get update && apt-get install -y build-essentials
COPY main.c Makefile /src/
WORKDIR /src/
RUN make build

During the image building process, the instructions in the Dockerfile will be executed from top to bottom, and the results of each construction step will be cached, as shown in the figure

If you build again at this time, you will directly use the results in the build cache (Using cache)

Now assume that the code in main.c is modified . When building again, starting from the command COPY main.c Makefile /src/ , subsequent build caches will be invalidated, as shown in the figure below

If you don't want to use the build cache, you can pass --no-cache when executing the build command

(6) Mirror image construction process

After the Docker Client executes the build command, the final image will be built through the following steps

  1. Determine the build context, if there is a .dockerignore file in the build context, parse the matching rules of the file, and exclude the matched file resources in the build context
  2. Send Dockerfile and build context to Docker daemon
  3. The Docker daemon receives the build request. The following steps are all completed by the Docker daemon, omitting the subject
  4. Check whether the instructions in the Dockerfile are legal one by one, and if not, stop the build immediately. This step can determine how many construction steps there are in total, so that the current step can be displayed during subsequent step-by-step construction, such as  Step 1/2
  5. Execute the instructions in the Dockerfile one by one, and each instruction creates a new layer. A temporary container will be generated to execute the command, and the temporary container will be deleted after the step
  6. Generate the final image

2. Introduction to .dockerignore

.dockerignore is a text file used to exclude matching files or folders in the build context, which is very similar to .gitignore

The .dockerignore file needs to be placed in the root directory of the build context. Before the Docker Client sends a build request, it will check whether the file exists. If the file exists, it will parse the file, delete the matching file resources from the build context, and then send the remaining files in the build context to the Docker daemon

(1) Grammatical rules

This file needs to follow certain grammar rules

  1. Lines starting with # are comments and will not be parsed as matching rules
  2. Support ? wildcard, match a single character
  3. Support * wildcard, match multiple characters, only match single-level directory
  4. Support ** wildcards, which can match multi-level directories
  5. Support ! matcher, declaring that certain file resources do not need to be excluded
  6. Dockerfile and .dockerignore files can be excluded with .dockerignore. Docker Client will still send these two files to the Docker daemon, because the underlying Docker needs. But the ADD and COPY instructions cannot operate these two files

(2) Example

A .dockerignore file is as follows

# this is a .dockerignore demo

*/demo*
*/*/demo*
demo?
**/mydemo*

Description of matching rules, assuming that the root directory of the build context is /

  1. The first line is a comment, ignore
  2. */demo* means to exclude folders or files starting with demo in the first-level directory in the build context, such as /test/demo-file.txt and /another/demo-directory/ will be excluded
  3. */*/demo* means to exclude files or folders starting with demo in the second-level directory in the build context
  4. demo? Indicates to exclude files or folders starting with demo and followed by only one other character in the build context, such as demo1, demob
  5. **/mydemo* means to exclude files or folders starting with mydemo in any directory in the build context

Another .dockerignore file is as follows, assuming the build context root directory is /

# this is another .dockerignore demo

*.md
!README*.md
README-secret.md

Description of matching rules, assuming that the root directory of the build context is / 

  1. *.md means to exclude all Markdown files under the root directory of the build context
  2. !README*.md indicates that Markdown files starting with README do not need to be excluded
  3. README-secret.md indicates that this file also needs to be excluded

3. Introduction to Dockerfile

Dockerfile is a text file used to describe the process of building a Docker image. This file can contain multiple build instructions and related descriptions

The build instructions of the Dockerfile need to follow the following syntax

# Comment
INSTRUCTION arguments

Most of the lines starting with # are comments, and a small part are parser instructions

The build instruction is divided into two parts, the first part is the instruction, and the second part is the instruction parameter. Commands are not case-sensitive, but by convention, it is recommended to use uppercase, so that it is not easy to be confused with command parameters

(1) Parser directive / parser directive

The parser instruction also starts with # , which is used to prompt the interpreter to perform special processing on the Dockerfile. It will not add a mirror layer during the build process, nor will it appear during the build process

Parser directives are optional, if defined, follow the syntax

# directive=value

# 解析器指令需要在空行、注释、构建指令之前

Precautions

  • The same parser directive cannot be repeated
  • Case insensitive, by convention, lower case is recommended
  • After empty lines, comments, and build instructions, Docker no longer looks for parser instructions, and treats them as comments
  • By convention, parser directives are placed on the first line of a Dockerfile, followed by an empty line
  • Spaces within a line are ignored, and cross-lines are not supported

Docker currently supports two parser directives

  1. syntax
  2. escape

syntax parser directive, only takes effect when using BuildKit as the builder

The escape parser directive to specify the use of escape characters in Dockerfiles

In Dockerfile, escape defaults to \ 

# escape=\  

But \ in Windows system is a path separator, it is recommended to replace escape with `, which is consistent with PowerShell

# escape=`

(2) Detailed Explanation of Common Commands

Overview of common commands

serial number command name Functional description
1 FROM Specify base image or parent image
2 LABEL Add metadata to images
3 ENV set environment variables
4 WORKDIR Specify the working directory for subsequent instructions, similar to the cd command in Linux
5 USER Specifies the default user for the current build phase and container runtime, and an optional user group
6 VOLUME

Create a mounted data volume with a specified name for data persistence

7 ADD Copy the files in the specified directory in the build context to the specified location in the mirror file system
8 COPY The function and syntax are similar to ADD, but it will not automatically decompress files, nor can it access network resources
9 EXPOSE Agree on the port that the container listens to when running, usually used for communication between the container and the outside world
10 RUN Used to execute commands during image building
11 CMD After the image is successfully built, the command executed when the created container starts, often used in conjunction with ENTRYPOINT
12 ENTRYPOINT

Used to configure the container to run in an executable mode, often used in conjunction with CMD

FROM

Specify base image or parent image

语法
  FROM [--platform=<platform>] <image> [AS <name>]
  FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
  FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
示例
  FROM redis
  FROM redis:7.0.5
  FROM redis@7614ae9453d1

Precautions

  1. tag or digest is optional, if not specified, the latest version will be used as the base image
  2. If it is not based on any image, the writing method is: FROM scratch. Scratch is an empty image, which can be used to build ultra-small images such as debian, busybox, etc., and truly build images from scratch

LABEL

Add metadata to images

语法
  LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例
  LABEL author="Jason 315" version="1.0.0" description="Dockerfile案例"
  LABEL author="Jason 315" \
        version="1.0.0" \
        description="Dockerfile案例"

Precautions

  1. LABEL defines the metadata of the key-value pair structure. The same LABEL instruction can specify multiple metadata, separated by spaces, on the same line, or separated by backslashes, placed on multiple lines
  2. When defining metadata values, try to use double quotes instead of single quotes, especially when using string interpolation
  3. The current image can inherit the metadata from the base image or parent image, or it can override
  4. You can view metadata with the following command

docker image inspect -f='{ {json .ContainerConfig.Labels}}' my-image

ENV

set environment variables

语法
  ENV <key>=<value> ...
  ENV <key> <value>
示例
  ENV MY_NAME="Jason315" MY_CAT="Tomcat"
  ENV MY_CAT Kitty

Precautions

  1. The first method can set multiple environment variables at the same time with one command, and supports quotation marks and backslashes as continuation symbols
  2. The second method can only set one environment variable at a time, and the part after the key is value. Docker officially does not recommend this way of writing, and indicates that later versions may delete this way of writing
  3. The current image can inherit the environment variables in the base image or parent image, or override them. Therefore, be careful when defining environment variables, such as ENV DEBIAN_FRONTEND=noninteractive will change the default behavior of apt-get
  4. Environment variables defined using the ENV directive will eventually be persisted in the container
  5. You can override the environment variables defined in the image by --env <key>=<value> or -e <key>=<value> when running the container
  6. For variables that are only used during image building, it is recommended to use ARG , or inline environment variables, so that they will not be persisted into the final image
  7. An example of an inline environment variable RUN TEMP_NAME="no persistit" ...
  8. View the environment variables in the final image

docker image inspect -f='{ {json .ContainerConfig.Env}}' my-image 

WORKDIR

Specify the working directory for subsequent instructions, similar to the cd command in Linux

语法
  WORKDIR /path/to/workdir
示例
  WORKDIR /a
  WORKDIR b
  WORKDIR c
备注
  当前工作目录为 /a/b/c

 Use environment variables set in Dockerfile

# 其他指令
ENV DIR_PATH=/demo
WORKDIR $DIR_PATH/$DIR_NAME
RUN pwd

When building a mirror, the output of pwd is /demo, because $DIR_NAME is not specified, just ignore it

Precautions

  1. The default working directory is /, which will be created automatically even if it is not explicitly specified and no instructions are used.
  2. The specified environment variables can be displayed in the Dockerfile, including the environment variables in the parent image
  3. In the same Dockerfile, the WORKDIR command can be used multiple times. If a relative path is set, it will be appended to the path specified by the previous WORKDIR command
  4. After setting WORKDIR, the related operations of the subsequent RUN, CMD, ENTRYPOINT, ADD, COPY instructions are performed in the current working directory
  5. Since the parent mirror may also set the working directory, in order to avoid operating in an unknown directory, the best practice is to display the working directory of the current mirror

USER

Specifies the default user for the current build phase and container runtime, and an optional user group

语法
  USER <user>[:<group>]
  USER <user>[:<GID>]
  USER <UID>[:<GID>]
  USER <UID>[:<group>]
示例
  USER jason315
  USER jason315:jasonGroup

Precautions

  1. When specifying a user, you can specify a username or a user ID (UID)
  2. User group is optional, user group name or user group ID (GID) can be specified
  3. After using USER to specify a user, the subsequent RUN , CMD , and ENTRYPOINT instructions in the Dockerfile will use this user. In addition, this user is also the default user when the container is running
  4. When running the container, the default user set in the Dockerfile can be overridden by the -u parameter
  5. When no user group is specified, the default user group root is used
  6. When specifying a non-built-in user in the Windows system, you need to use the net user /add command to create the user first
FROM microsoft/windowsservercore
# 在容器中创建 Windows 用户
RUN net user /add my_user
# 设置后续指令的用户
USER my_user

VOLUME 

Create a mounted data volume with a specified name for data persistence

语法
  VOLUME ["volume1", "volume2", ...]
  VOLUME volume1 volume2 ...
示例
  VOLUME ["/demo/data", "/demo/logs"]
  VOLUME /myvol

Function and characteristics

  1. Data persistence to avoid loss of important data after container restart
  2. When the data volume is modified, the container will not be affected, preventing the container from expanding
  3. It is beneficial for multiple containers to share data

Precautions

  1. When defined in the form of an array, it will be parsed as a JSON array, and double quotes must be used instead of single quotes
  2. After defining VOLUME, the modifications made to the data volume by subsequent instructions of Dockerfile will be discarded

ADD

Copy the file (src) under the specified directory in the build context to the specified location (dest) of the mirror file system

语法
  ADD [--chown=<user>:<group>] [--checksum=<checksum>] <src>... <dest>
  # 路径中含有空格的情况,可以使用第二种方式
  ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
  # 处于实验阶段的特性,直接添加 Git 资源到镜像文件系统中
  ADD <git ref> <dir>
示例
  ADD demo.txt /dest_dir/demo.txt    # 将 demo.txt 复制到 /dest_dir 下的 demo.txt
  ADD demo* /dest_dir/               # 将以 demo 开头的文件复制到 /dest_dir 下
  ADD dem?.txt /dest_dir/            # ? 被一个单字符替换,可以是 demo.txt, 将符合条件的文件复制到 /dest_dir 下
  ADD test/ /dest_dir/               # 将 test 文件夹下的所有文件都复制到 /dest_dir/ 下
  ADD test/ dest_dir/                # 将 test 文件夹下的所有文件都复制到 <WORKDIR>/dest_dir/ 下
  ADD http://example.com/a/url.txt / # 从 URL 下载 url.txt 文件,另存为文件 /a/url.txt,其中文件夹 /a/ 是自动创建的

Syntax when src contains special characters

# 假设文件名为 demo[0].txt, 其中含有特殊符号 [ 和 ]
ADD demo[[]0].txt /dest_dir

Precautions

  1. If the src resource corresponding to an ADD instruction is changed, the build cache after this instruction in the Dockerfile will be invalid
  2. The --chown feature is only supported when the Dockerfile is used to build Linux containers, not when building Windows containers
  3. src supports setting multiple file resources, each file resource will be resolved to a relative path in the build context
  4. src supports wildcards , mainly * and ?, which are matched by the filepath.Match rule of Go language
  5. When folders or files in src contain special characters, they need to be escaped to prevent them from being regarded as matching patterns
  6. If src is a folder, all files under it will be copied, including filesystem metadata
  7. If src contains multiple file resources, or wildcards are used, dest must be a folder, that is, dest ends with /
  8. If src is a compressed resource , it will be decompressed into a folder, but the compressed resource corresponding to the remote URL will not be decompressed. In addition, empty files ending in a compressed format will not be decompressed, but will be copied to the target location as a normal file
  9. If src is a remote URL, and dest does not end with /, Docker downloads the file from the URL and saves it in dest
  10. If src is a remote URL, the URL contains a non-empty path, and dest ends with /, Docker will infer the filename, create the same path in the target location according to the path in the URL, and put the downloaded file into it
  11. dest can be an absolute path under the mirror file system, or a relative path under WORKDIR
  12. If dest does not end with /, Docker will treat it as a normal file, and the contents of src will be written into this file
  13. If some directories under the target location do not exist, they will be created automatically
  14. ADD does not support identity authentication when adding network resources, you can use RUN wget or RUN curl to achieve this function

COPY

The function and syntax are similar to ADD, but it will not automatically decompress files, nor can it access network resources

语法
  COPY [--chown=<user>:<group>] <src>... <dest>
  COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

EXPOSE

Agree on the port that the container listens to when running, usually used for communication between the container and the outside world

语法
  EXPOSE <port> [<port>/<protocol>...]
示例
  EXPOSE 8080
  EXPOSE 80/tcp
  EXPOSE 80/udp
  EXPOSE 9090/tcp 9090/udp

Precautions

  1. Support TCP or UDP protocol, if no protocol is specified explicitly, TCP protocol is used by default
  2. When the same port needs to be exposed in the form of TCP and UDP protocols at the same time, it needs to be specified separately
  3. EXPOSE does not actually publish the port to the host, but as a convention, let the image user use -p to publish the agreed ports respectively, or -P to publish all agreed ports when running the container
  4. If the port is not exposed, the running container can also map the port by -p

RUN

Used to execute commands during image building, there are two execution methods

The first one is executed in shell mode

语法
  RUN <command>
示例
  RUN echo "Hello Dockerfile" 

In this way, the command is executed by the shell, the default shell of the Linux system is /bin/sh -c , and the default shell of the Windows system is cmd /S /C . The default shell  can be modified by the SHELL command

The second is to execute in exec mode

语法
  RUN ["executable", "param1", "param2"]
示例
  RUN ["echo", "Hello Dockerfile"]
  RUN ["sh", "-c", "echo $HOME"]
  RUN ["/bin/bash", "-c", "echo", "Hello Dockerfile"] 

Some shell processing, such as environment variable substitution, is not done this way. If you want to perform operations such as variable substitution, there are two solutions, one is to execute in the Shell mode, and the other is to directly execute the sh command. The final variable substitution processing is done by the shell, not by Docker

# 方式一,回到 Shell 执行方式
RUN echo $HOME
# 方式二,直接执行 sh 命令
RUN ["sh", "-c", "echo $HOME"]

Precautions

  1. The exec method is parsed through a JSON array, so use double quotes instead of single quotes
  2. Backslash \ needs to be escaped under Windows system
  3. Each time the RUN command is executed, a new image layer will be created. In order to avoid creating too many mirror layers, you can use the && symbol to connect multiple commands
  4. The RUN instruction cache is not automatically invalidated during the next build. When building a mirror image, you can use the --no-cache flag to invalidate the instruction cache; in addition, if the file resources corresponding to the ADD and COPY instructions are changed, the subsequent RUN instruction cache will also be invalidated

CMD

After the image is built successfully, the command executed when the created container starts. There are 3 forms of CMD command

语法
  CMD command param1 param2 # shell 方式
  CMD ["executable","param1","param2"] # exec 方式,这是推荐的方式
  CMD ["param1","param2"]   # 作为 ENTRYPOINT 的默认参数,这种方式是 exec 方式的特殊形式
示例
  CMD echo "Hello Dockerfile"
  CMD ["echo", "Hello Dockerfile"]
  
  FROM ubuntu
  CMD ["/usr/bin/wc", "--help"]

Precautions

  1. Only one CMD command can take effect in a Dockerfile, even if multiple are specified, only the last one will take effect
  2. Although only the last CMD takes effect in Dockerfie, each CMD command will add a mirror layer, so only one CMD command is defined, and multiple commands can be connected by &&
  3. The exec method is parsed through a JSON array, so use double quotes instead of single quotes
  4. Different from the RUN command, the RUN command is executed during the process of building the image, and the CMD command is executed when the container starts
  5. The command line parameters after docker run <image> will override the commands in CMD

ENTRYPOINT

Used to configure the container to run as an executable. The ENTRYPOINT instruction has 2 forms

语法
  ENTRYPOINT ["executable", "param1", "param2"] # 推荐方式
  ENTRYPOINT command param1 param2
示例 1
  FROM ubuntu
  ENTRYPOINT ["top", "-b"]
  CMD ["-c"]
示例 2
  FROM ubuntu
  ENTRYPOINT exec top -b

Precautions

  1. Only the last ENTRYPOINT instruction in the Dockerfile takes effect
  2. When running a container, you can override the ENTRYPOINT directive with docker run --entrypoint
  3. If the ENTRYPOINT in the form of exec is specified, the command line parameters in docker run <image> will be appended to the end of the JSON array
  4. The exec method is parsed through a JSON array , so use double quotes instead of single quotes
  5. The shell form of ENTRYPOINT invalidates the command line arguments in the CMD command and docker run <image>. It has the disadvantage that the ENTRYPOINT command will be a subcommand of /bin/sh -c and will not pass the signal. For example, when the container is stopped, the SIGTERM signal cannot be received in the container. This is not the expected effect. It can be solved by adding exec before the command, such as ENTRYPOINT exec top -b
  6. After specifying ENTRYPOINT, the content of CMD will be passed to the ENTRYPOINT command as the default parameter, in the form of <ENTRYPOINT> <CMD>
  7. If CMD is defined in the base image, the ENTRYPOINT defined by the current image will reset the value of CMD to a null value. In this case, CMD needs to be redefined

(3) Introduction to other instructions

MAINTAINER(deprecated)

Set the Author field of the image, the new version will be obsolete, it is recommended to use LABEL instead

语法
  MAINTAINER <name>
示例
  MAINTAINER jason315

ARG

Define build variables to receive external parameters in Dockerfile, these variables will not be persisted to the image layer

语法
  ARG <name>[=<default value>]
示例 1
  ARG build_user # 不带默认值的构建变量
  ARG build_comment="built by somebody" # 带默认值的构建变量
示例 2
  ARG build_user=Jason315
  ENV build_user=Jason520
  RUN echo $build_user # 此时 build_user 已经被 ENV 指令覆盖为 Jason520

When building a mirror, build variables can be passed in via --build-arg

docker build -t my-img --build-arg build_user=Jason315 .

Docker has a set of predefined build variables that can be used directly

  • HTTP_PROXY | http_proxy
  • HTTPS_PROXY | https_proxy
  • FTP_PROXY | ftp_proxy
  • NO_PROXY | no_proxy
  • ALL_PROXY | all_proxy

Precautions

  1. Passing sensitive information using build variables is deprecated
  2. For build variables with default values , if parameters are passed in during construction, the parameters passed in will be used in the Dockerfile, if not passed in, default values ​​will be used
  3. Build variables take effect from the line defined in the Dockerfile until the end of the current build phase
  4. Build variables will be overwritten by environment variables of the same name defined later
  5. Build variables will not be persisted into the image layer, but changes to the build variable may invalidate the build cache , which will trigger when the build variable is first used, rather than the line where it is defined

STOP SIGNAL

Sets the syscall signal sent to the container to execute exit when docker stop. The signal can be a signal name of the form SIG<NAME>, such as SIGKILL; it can also be an unsigned number matching a position in the kernel system call table, such as 9

语法
  STOPSIGNAL signal
示例
  STOPSIGNAL SIGTERM
  STOPSIGNAL 9

Precautions

  1. If not specified explicitly, the default STOPSIGNAL is SIGTERM
  2. STOPSIGNAL can be overridden by --stop-signal when creating or running a container

HEALTHCHECK

Execute certain commands in the container to check the health of the container and confirm whether the container is still running normally

语法
  HEALTHCHECK [OPTIONS] CMD command # 在容器内运行命令,检查容器的健康状况
  HEALTHCHECK NONE # 禁用任何健康检查,包括从基础镜像继承而来的
CMD 前的可选参数
  --interval=DURATION (执行时间间隔,默认值 30s)
  --timeout=DURATION (执行单次命令的超时时间,如果超时,会增加失败次数,默认值 30s)
  --start-period=DURATION (启动时间,在该时间段内,检查失败不计入总失败次数,默认值 0s)
  --retries=N (健康检查失败后的重试次数,默认值 3)
示例
  HEALTHCHECK --interval=5m --timeout=3s \
    CMD curl -f http://localhost/ || exit 1

There are 3 situations for the exit status code of the health check command

  • 0: healthy - the container is running normally and is available
  • 1: unhealthy - the container is in an abnormal running state and is unavailable
  • 2:reserved - no exit status code used

Precautions

  1. The HEALTHCHECK instruction is defined in the Dockerfile. After the container is started, the Health Status (Health Status) item will be added to the status, and the value is healthy or unhealthy
  2. In the same Dockerfile, only the last HEALTHCHECK takes effect

SHELL

Set the default shell for commands executed in shell mode, these commands include RUN, CMD, ENTRYPOINT

语法
  SHELL ["executable", "parameters"]
示例 1
  FROM ubuntu
  SHELL ["/bin/sh", "-c"]
示例 2
  FROM microsoft/windowsservercore
  SEHLL ["powershell", "-command"]

Precautions

  1. The default shell of the Linux system is ["/bin/sh", "-c"]
  2. The default shell of Windows system is ["cmd", "/S", "/C"]
  3. The SHELL command can be used multiple times and affects the subsequent RUN, CMD, ENTRYPOINT commands executed in shell mode

ONBUILD

Add a trigger instruction to an image that is executed when the image is used as the base image of another image. Simply put, another Dockerfile's FROM command uses this image as a parent image to trigger execution

语法
  ONBUILD <INSTRUCTION>
定义 ONBUILD 的 Dockerfile
  FROM ubuntu
  ONBUILD ["echo", "I'm used as a base image"]
构建父级镜像
  docker build -t onbuild-image .
触发 ONBUILD 的 Dockerfile
  FROM onbuild-image
  RUN ["echo", "I just trigger the ONBUILD instruction"]

View the list of triggers that define the image exposed by ONBUILD

docker inspect -f='{
   
   {json .ContainerConfig.OnBuild}}' onbuild-image

Precautions 

  1. Build commands other than FROM, MAINTAINER, ONBUILD can be used as trigger commands
  2. The trigger command will not affect the image where the trigger command is defined. After the build is completed, the trigger list will be saved in the ONBUILD attribute in the metadata of the current image, which can be viewed with the docker inspect command

reference documents

Dockerfile official documentation

Detailed explanation of Dockerfile

Guess you like

Origin blog.csdn.net/u013481793/article/details/128338417