[LINUX] Dockerfile reference Japanese translation

Japanese translation of Dockerfile reference.

Docker can build the image automatically by reading the instructions from the Dockerfile. Dockerfile is a text document that describes commands for building images. Called and used by the user from the command line. The docker build (https://qiita.com/JhonnyBravo/items/87976fe9de47ed58b8b1) allows users to create automatic builds that execute multiple command line instructions in succession.

This page describes the commands you can use in your Dockerfile. After reading this page, see Dockerfile Best Practices for a tip-oriented guide.

how to use

The docker build command builds an image from a Dockerfile and context. The build context is a set of files in the PATH or URL at the specified location. PATH is a directory on your local file system. The URL is the location of your Git repository.

The context is processed recursively. Therefore, the PATH contains subdirectories and the URL contains the repository and its submodules. The following example shows a build command that uses the current directory as the context.

$ docker build .

Sending build context to Docker daemon  6.51 MB
...

The build is done by the Docker daemon, not the CLI. The first thing the build process does is send the entire context (recursively) to the daemon. In most cases, it's a good idea to start with an empty directory as the context and keep the Dockerfile in that directory. Add only the files needed to build the Dockerfile.

** Warning ** Do not use the root directory / as your PATH. The entire contents of the hard drive are transferred to the Docker daemon when the build is run.

When using a file in the build context, Dockerfile references the file specified by an instruction such as the COPY instruction. To improve build performance, add the .dockerignore file to the context directory to exclude the files and directories. See the documentation on this page for instructions on how to create a .dockerignore file.

By convention, the Dockerfile is placed at the root of the context, You can use the -f flag in the docker build to specify a Dockerfile anywhere in the filesystem. ..

$ docker build -f /path/to/a/Dockerfile .

You can specify the repository and tags to save the new image if the build is successful.

$ docker build -t shykes/myapp .

To tag the image to multiple repositories after the build, add multiple -t parameters when running the build command.

$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

The Docker daemon performs a pre-validation of the Dockerfile before executing the instructions in the Dockerfile and returns an error if the syntax is incorrect.

$ docker build -t test/myapp .

Sending build context to Docker daemon 2.048 kB
Error response from daemon: Unknown instruction: RUNCMD

The Docker daemon executes the instructions in the Dockerfile one at a time, commits the result of each instruction to a new image as needed, and finally prints the ID of the new image. The Docker daemon automatically cleans up the context you submit.

Note that each instruction is executed independently and creates a new image. Therefore, RUN cd / tmp does not affect the following instructions.

Whenever possible, Docker reuses intermediate images (caches) to significantly speed up the Docker build process. Intermediate image reuse is indicated by the `ʻUsing cache`` message in the console output. (See the Dockerfile Best Practices Guide (https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/) for more information)

$ docker build -t svendowideit/ambassador .

Sending build context to Docker daemon 15.36 kB
Step 1/4 : FROM alpine:3.2
 ---> 31f630c65071
Step 2/4 : MAINTAINER [email protected]
 ---> Using cache
 ---> 2a1c91448f5f
Step 3/4 : RUN apk update &&      apk add socat &&        rm -r /var/cache/
 ---> Using cache
 ---> 21ed6e7fbb73
Step 4/4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
 ---> Using cache
 ---> 7ea8aef582cc
Successfully built 7ea8aef582cc

The build cache is only used from the local image that has the parent chain. This means that the image was created by a previous build or the entire chain of images was loaded with docker load. If you want to use the build cache for a particular image, you can specify it with the --cache-from option. The image specified by --cache-from does not need to have a parent chain and can be retrieved from other registries.

Once the build is complete, you're ready to consider how to push the repository to the registry.

BuildKit

Docker version 18.09 and later supports a new backend for performing builds provided by the moby / buildkit project. The BuildKit backend has many advantages over older implementations. For example, BuildKit can:

To use the BuildKit backend, you must set the environment variable DOCKER_BUILDKIT = 1 in the CLI before calling docker build.

See the BuildKit repository documentation (https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md) for the experimental Dockerfile syntax you can use with BuildKit-based builds. please.

Format

The format of the Dockerfile is:

# Comment
INSTRUCTION arguments

The instructions are not case sensitive. However, it is customary to capitalize it to distinguish it from its arguments.

Docker executes the instructions in the Dockerfile in sequence. The Dockerfile must start with the FROM instruction. This can be after parser directives, comments, and the global scope `ʻARG. The FROMinstruction specifies the parent image from which it was built. The FROM can only be preceded by one or more ```ARG instructions that declare the arguments used on the FROM line of the Dockerfile.

Docker treats lines starting with # as comments unless the line is a valid parser directive. # markers elsewhere in the line are treated as arguments. This allows statements such as:

# Comment
RUN echo 'we are running some # of cool things'

The comment line is removed before the Dockerfile instruction is executed. That is, the comments in the following example are not processed by the shell that executes the `ʻecho`` command. Both examples below are equivalent.

RUN echo hello \
# comment
world
RUN echo hello \
world

Line continuation characters are not supported in comments.

** Notes on whitespace **

For backward compatibility, leading whitespace before comments (#) and instructions (such as RUN) is ignored, but not recommended. In these cases, leading whitespace is not preserved, so the following example is equivalent.

         # this is a comment-line
   RUN echo hello
RUN echo world
# this is a comment-line
RUN echo hello
RUN echo world

However, blanks in instruction arguments such as commands following RUN are preserved, so in the following example, hello world is output with leading blanks.

RUN echo "\
    hello\
    world"

Parser directive

Parser directives are optional and affect how subsequent lines in the Dockerfile are processed. Parser directives do not add layers to the build and do not appear as build steps. Parser directives are written as a special type of comment in the form # directive = value. A directive can only be used once.

When comments, empty lines, or builder instructions are processed, Docker no longer looks for parser directives. Treats what is written as a parser directive as a comment and does not try to verify if it may be a parser directive. Therefore, all parser directives must be at the top of the Dockerfile.

Parser directives are not case sensitive. However, by convention it should be lowercase. By convention, you can also include a blank line after the parser directive. Line continuation characters are not supported in parser directives.

Due to these rules, all of the following examples are invalid:

Invalid due to line continuation

# direc \
tive=value

Invalid because it is displayed twice

# directive=value1
# directive=value2

FROM ImageName

It is treated as a comment because it appears after the builder's instructions.

FROM ImageName
# directive=value

It is treated as a comment because it appears after a comment that is not a parser directive.

# About my dockerfile
# directive=value
FROM ImageName

`ʻUnknowndirectiveis treated as a comment because it is not recognized. In addition, knowndirective`` is treated as a comment because it appears after a comment that is not a parser directive.

# unknowndirective=value
# knowndirective=value

The parser directive allows whitespace without line breaks. Therefore, the following lines are all treated the same.

#directive=value
# directive =value
#	directive= value
# directive = value
#	  dIrEcTiVe=value

The following parser directives are supported.

syntax

# syntax=[remote image reference]

Example

# syntax=docker/dockerfile
# syntax=docker/dockerfile:1.0
# syntax=docker.io/docker/dockerfile:1
# syntax=docker/dockerfile:1.0.0-experimental
# syntax=example.com/user/repo:tag@sha256:abcdef...

This feature is only enabled when the BuildKit backend is used.

The syntax directive defines the location of the Dockerfile builder used to build the current Dockerfile. The BuildKit backend allows you to seamlessly use an external implementation of the builder that is distributed as a Docker image and runs inside a container sandbox environment.

The custom Dockerfile implementation allows you to:

Official release

Docker distributes the official version of the image that can be used to build a Dockerfile in the docker / dockerfile repository on DockerHub. There are two channels for new images to be released: stable and experimental.

Stable channels follow semantic versioning.

Example:

The experimental channel uses incremental versioning with major and minor components from the stable channel at release.

Example:

You need to choose the channel that suits your needs. If you only need to fix bugs, you need to use docker / dockerfile: 1.0. If you want to take advantage of experimental features, you need to use the experimental channel. If you are using the experimental channel, we recommend that you use the immutable full version variant, as new releases may not be backward compatible.

See Source Repository Description (https://github.com/moby/buildkit/blob/master/README.md) for master builds and nightly feature releases.

escape

# escape=\ (backslash)

Or

# escape=` (backtick)

Escape directives set the characters used to escape the characters in the Dockerfile. If not specified, the default escape character is \.

Escape characters are used both to escape characters in a line and to escape newlines. This allows the Dockerfile instruction to span multiple lines. Note that escaping is not performed with the RUN command, except at the end of the line, regardless of whether the ```escape`` parser directive is included in the Dockerfile.

Setting the escape character to "` "is especially useful on Windows. Here \ is the directory path delimiter. "` "Is consistent with Windows PowerShell.

Consider the following example, which fails in a non-trivial way on Windows. The second \ at the end of the second line is interpreted as a newline escape, not the target of the escape from the first \. Similarly, the \ at the end of the third line is treated as a continuation of the line if it was actually treated as an instruction. The result of this dockerfile is that the second and third lines are considered a single instruction.

FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\

Execution result:

PS C:\John> docker build -t cmd .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/2 : COPY testfile.txt c:\RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS C:\John>

One of the above solutions is to use / as the target for both the COPY instruction and the dir. However, this syntax is confusing because it is not natural in Windows paths. In the worst case, not all Windows commands support / as the path delimiter, which makes it error prone.

By adding the `ʻescape`` parser directive, the following Dockerfile will succeed as expected using natural platform semantics in the Windows file path.

# escape=`

FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\

Execution result:

PS C:\John> docker build -t succeeds --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1/3 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/3 : COPY testfile.txt c:\
 ---> 96655de338de
Removing intermediate container 4db9acbb1682
Step 3/3 : RUN dir c:\
 ---> Running in a2c157f842f5
 Volume in drive C has no label.
 Volume Serial Number is 7E6D-E0F7

 Directory of c:\

10/05/2016  05:04 PM             1,894 License.txt
10/05/2016  02:22 PM    <DIR>          Program Files
10/05/2016  02:14 PM    <DIR>          Program Files (x86)
10/28/2016  11:18 AM                62 testfile.txt
10/28/2016  11:20 AM    <DIR>          Users
10/28/2016  11:20 AM    <DIR>          Windows
           2 File(s)          1,956 bytes
           4 Dir(s)  21,259,096,064 bytes free
 ---> 01c7f3bef04f
Removing intermediate container a2c157f842f5
Successfully built 01c7f3bef04f
PS C:\John>

Environment variable replacement

Environment variables (declared with the `ʻENV`` statement) can also be used in certain instructions as variables interpreted by the Dockerfile. Escapes are also processed to include variable-like syntax in the statement as is.

Environment variables are represented in the Dockerfile as either $ variable_name or $ {variable_name}. They are treated equally and the curly braces syntax is usually used to address the problem of variable names with no whitespace, such as $ {foo} _bar.

The $ {variable_name} syntax also supports some of the standard bash modifiers specified below.

In all cases word can be any string that contains additional environment variables.

Escape is possible by prepending \ to the variable. For example, \ $ foo or \ $ {foo} is converted to $ foo and $ {foo}.

Example (The parsed representation appears after #):

FROM busybox
ENV FOO=/bar
WORKDIR ${FOO}   # WORKDIR /bar
ADD . $FOO       # ADD . /bar
COPY \$FOO /quux # COPY $FOO /quux

Environment variables are supported by the instructions shown below in the Dockerfile.

Environment variable substitution uses the same value for each variable throughout the instruction. In other words, in this example:

ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc

The result is a def with a value of hello instead of a bye. However, ghi is not part of the same instruction that set ```abcto bye, so it has a value of bye``.

.dockerignore file

The docker CLI looks for a file named .dockerignore in the context's root directory before sending the context to the docker daemon. If this file exists, the CLI changes the context to exclude files and directories that match the pattern in it. This avoids unnecessarily sending large or sensitive files or directories to the daemon or adding them to the image using ʻADD`` or `COPY``.

The CLI interprets the .dockerignore file as a newline-separated list of patterns, similar to Unix shell file globs. For collation purposes, the root of the context is considered to be both the working directory and the root directory. For example, the patterns / foo / bar and foo / bar are both bar` at the root of the git repository in the foosubdirectory of PATH`` or in the URL. Exclude files or directories named `. Neither excludes the other.

If a line in the .dockerignore file begins with # in the first column, this line is considered a comment and is ignored before being interpreted by the CLI.

Here is an example of writing a .dockerignore file:

# comment
*/temp*
*/*/temp*
temp?

This file causes the following build behavior:

rule motion
# comment Ignore it.
*/temp* A direct subdirectory of the root, namedtempExclude files and directories that start with. For example, a plain file/somedir/temporary.txtIs excluded and the directory/somedir/tempIs also excluded.
*/*/temp* From a subdirectory two levels below the roottempExclude files and directories that start with. For example/somedir/subdir/temporary.txtIs excluded.
temp? The name is temp+Excludes files and directories in the root directory that are a single character. For example/tempaWhen/tempbIs excluded.

Matching is done using Go's filepath.Match rule. The preprocessing step uses Go's filepath.Clean to remove leading and trailing whitespace, and removes . and .. elements. Blank lines are ignored after preprocessing.

In addition to Go's filepath.Match rule, Docker also supports the special wildcard string ** that matches any number of directories (including zeros). For example, ** / *. Go excludes all files ending in .go in all directories that contain the root of the build context.

You can use lines that start with ! (exclamation point) to create exclusion exceptions. The following is an example of a .dockerignore file that uses this mechanism.

*.md
!README.md

All markdown files except README.md are excluded from the context.

The placement of the ! exception rule affects its behavior. The last line of .dockerignore that matches a particular file determines whether the file is included or excluded. Consider the following example.

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

Markdown files are not included in the context, except for README files other than README-secret.md.

Now consider this example.

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

Contains all README files. The middle line has no effect because ! README * .md matches README-secret.md and comes at the end.

You can also use the .dockerignore file to exclude the Dockerfile and .dockerignore files. These files will continue to be sent to the daemon as they need to run the job. However, the ```ADDand COPY`` instructions do not copy them to the image.

Finally, it's a good idea to specify the files to include in the context, not the files to exclude. To achieve this, specify * as the first pattern, followed by one or more ! Exception patterns.

** Caution **

For historical reasons, the pattern . is ignored.

FROM

FROM [--platform=<platform>] <image> [AS <name>]

Or

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

Or

FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

The FROM instruction initializes a new build stage and sets the base image for subsequent instructions. Therefore, a valid Dockerfile must start with the FROM instruction. The image can be any valid image. It's especially easy to start by getting the image from a public repository.

You can use the optional --platform flag to specify the platform of the image when FROM references a multi-platform image. For example, linux / amd64, linux / arm64, or windows / amd64. By default, the target platform of the build request is used. You can use global build arguments for the value of this flag. For example, you can use the automatic platform argument to force a stage to a native build platform and use it to cross-compile to the target platform within the stage. ( --platform=$BUILDPLATFORM )

Understand the interaction between ```ARGand FROM``

The FROM instruction supports variables declared by the ```ARGinstruction that occurs before the first FROM``.

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD  /code/run-app

FROM extras:${CODE_VERSION}
CMD  /code/run-extras

```ARGdeclared before FROMis outside the build stage and cannot be used in instructions after FROM. To use the default value of `ʻARG declared before the first FROM, use the` ʻARG`` instruction without a value in the build stage.

ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version

RUN

RUN has two forms:

The RUN instruction executes the command on a new layer on the current image and commits the result. The image with the committed result will be used in the next step in the Dockerfile.

Hierarchizing the RUN instruction and generating commits conforms to Docker's core concept of cheap commits and the ability to create containers from any point in the image history, like source control.

You can use the ```execformat to avoid changing the shell string or to run the RUN`` command with a base image that does not contain the specified shell executable.

The default shell format shell can be changed using the SHELL command.

In shell form, you can use \ (backslash) to continue a single RUN instruction on the next line. For example, consider the following two lines:

RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'

Together, they correspond to the following line:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'

To use another shell other than / bin / sh, use the `ʻexec`` format, which passes the desired shell. For example:

RUN ["/bin/bash", "-c", "echo hello"]

** Caution **

The> `ʻexec`` format is parsed as a JSON array.

That is, you must use double quotes ( ") before and after the word, not single quotes (').

Unlike the shell form, the ʻexec`` form does not call a command shell. This means that no normal shelling is done. For example, `` RUN [" echo", "$ HOME"] `` does not do variable substitution for `` $ HOME``. If shell processing is required, use the shell format or run the shell directly. Example: `` RUN ["sh", "-c", "echo $ HOME"] ``. If you run the shell directly using the ʻexec`` format, as in the shell format, it is the shell, not Docker, that expands the environment variables.

** Caution **

In JSON format, backslashes must be escaped. This is especially relevant for Windows, where the backslash is the path delimiter. The following line is treated as shell format because it is not valid JSON and fails in an unexpected way:

RUN ["c:\windows\system32\tasklist.exe"]

The correct syntax for this example is:

RUN ["c:\\windows\\system32\\tasklist.exe"]

The cache of RUN instructions is not automatically invalidated during the next build. Instruction caches such as RUN apt-get dist-upgrade -y will be reused in the next build. The cache for the RUN instruction can be disabled using the --no-cache flag (for example, docker build --no-cache).

See the Dockerfile Best Practices Guide (https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/) for more information.

The cache of the RUN instruction can be overridden by the ```ADDand COPY`` instructions.

Known issue ( RUN)

CMD

The CMD instruction has three forms:

There can only be one CMD instruction in a Dockerfile. If you list multiple CMDs, only the last CMD will be valid.

The main purpose of CMD is to provide default behavior for running containers. These default behaviors can include ʻexecutable`` or omit ʻexecutable. If you omit `ʻexecutable, you must also specify the` ʻENTRYPOINT`` instruction.

If you use CMD to provide the default arguments for the ENTRYPOINT`` instruction, you must specify both the `` CMD`` and ENTRYPOINT`` instructions in JSON array format. ..

** Caution **

The> `ʻexec`` format is parsed as a JSON array.

That is, you must use double quotes ( ") before and after the word, not single quotes (').

Unlike the shell form, the ʻexec`` form does not call a command shell. This means that no normal shelling is done. For example, `` CMD [" echo", "$ HOME"] `` does not do variable substitution with `` $ HOME``. If shell processing is required, use the shell format or run the shell directly. Example: `` CMD [" sh", "-c", "echo $ HOME"] `` If you run the shell directly using the ʻexec`` format, as in the shell format, it is the shell, not Docker, that expands the environment variables.

When used in shell or `ʻexecformat, the CMD`` instruction sets the command to be executed when the image is run.

When using the CMD shell format, <command> is executed with / bin / sh -c:

FROM ubuntu
CMD echo "This is a test." | wc -

If you want to execute <command> without a shell, you need to represent the command as a JSON array and specify the full path to ```executable. This array format is the recommended format for CMD``. The additional parameters must be represented individually as strings in the array.

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

If you want the container to run the same ʻexecutable`` every time, you should consider using ʻENTRYPOINTin combination with CMD. See `ʻENTRYPOINT.

If the user specifies an argument for docker run (https://qiita.com/JhonnyBravo/items/eee5a91682f1d7c72f6e), the default value specified in CMD will be overridden.

** Caution **

Do not confuse RUN with CMD. RUN actually executes the command and commits the result. CMD does nothing at build time, but specifies the command you want the image to execute.

LABEL

LABEL <key>=<value> <key>=<value> <key>=<value> ...

The LABEL instruction adds metadata to the image. LABEL is a key / value pair. To include spaces in the value of LABEL, use quotes and backslashes as you would for command line parsing.

Example of use:

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."

The image can have multiple labels. You can specify multiple labels on a line. Prior to Docker 1.10, this reduced the size of the final image, which is no longer the case. You can also specify multiple labels with a single instruction in one of two ways:

LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

Labels contained in the base image or parent image (the image in the FROM line) are inherited by the child image. If the label already exists but the values are different, the last applied value overwrites the previously set value.

Use the docker image inspect command to display the label of the image. You can only display labels using the --format option.

docker image inspect --format='' myimage
{
  "com.example.vendor": "ACME Incorporated",
  "com.example.label-with-value": "foo",
  "version": "1.0",
  "description": "This text illustrates that label-values can span multiple lines.",
  "multi.label1": "value1",
  "multi.label2": "value2",
  "other": "value3"
}

MAINTAINER (not recommended)

MAINTAINER <name>

The MAINTAINER instruction sets the `ʻAuthorfield in the generated image. The LABELinstruction gives you much more flexibility than the MAINTAINERto set the required metadata. Use LABELinstead. You can easily view it using, for example, docker inspect. To set the label corresponding to the MAINTAINER`` field:

LABEL maintainer="[email protected]"

This is displayed from docker inspect along with other labels.

EXPOSE

EXPOSE <port> [<port>/<protocol>...]

The `ʻEXPOSE`` instruction notifies Docker that it will listen on the network port specified when the container is executed. You can specify whether the port listens on TCP or UDP. If no protocol is specified, the default value is TCP.

The `ʻEXPOSEinstruction does not actually expose the port. It acts as a kind of document between the person who creates the image and the person who runs the container, and is intended to expose the port. To actually expose the ports when the container runs, use the -pflag in [docker run](https://qiita.com/JhonnyBravo/items/eee5a91682f1d7c72f6e) to make one or more ports. Publish and associate, or use the -P`` flag to expose all exposed ports and tie them to higher ports.

By default, `ʻEXPOSE`` assumes TCP, You can also specify UDP.

EXPOSE 80/udp

To publish over both TCP and UDP, write the following two lines:

EXPOSE 80/tcp
EXPOSE 80/udp

In this case, using -P on docker run (https://qiita.com/JhonnyBravo/items/eee5a91682f1d7c72f6e) exposes the port once for TCP and once for UDP. Note that -P uses a temporary higher host port on the host, so the ports are not the same for TCP and UDP.

You can override them at run time using the -p`` flag regardless of the ʻEXPOSE`` setting.

Example:

docker run -p 80:80/tcp -p 80:80/udp ...

See Using the -P flag to configure port redirection on the host system. The docker network command supports creating a network for communication between containers without having to expose or publish a specific port. This is because networked containers can communicate with each other over any port. For more information, see docker network feature overview (https://docs.docker.com/engine/userguide/networking/).

ENV

ENV <key>=<value> ...

The `ʻENVinstruction sets the environment variable to the value ``. This value is in the environment of all subsequent instructions in the build stage and can often be replaced inline. The value is interpreted for other environment variables and will be removed if the quotes are not escaped. As with command line parsing, you can use quotation marks and backslashes to include spaces in the value.

Example:

ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy

The `ʻENVinstruction allows you to set multiple = ... `` variables at once. In the example below, the final image will give the same final result.

ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
    MY_CAT=fluffy

Environment variables set using `ʻENVare preserved when the container is run from the resulting image. You can use docker inspectto view the value and use docker run --env = `` to change the value.

Persistence of environment variables can cause unexpected side effects. For example, setting ʻENV DEBIAN_FRONTEND = noninteractive`` changes the behavior of ʻapt-get`` and can confuse users of the image.

If the environment variables are only needed during the build and not in the final image, consider setting the value for a single command instead.

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...

Or use `ʻARG`` which is not preserved in the final image.

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y ...

** Alternative notation **

You can use the alternative syntax ʻENV <key> <value> `` in the> ʻENVstatement and omit.

Example:

ENV MY_VAR my-value

This syntax does not allow multiple environment variables to be set in a single ʻENV`` instruction, which can be confusing. Set a single environment variable ʻONEwith the value" TWO = THREE = world "``, for example:

ENV ONE TWO= THREE=world

Alternate syntax is supported for backward compatibility, but is deprecated for the reasons mentioned above and may be removed in a future release.

ADD

`ʻADD`` has two forms:

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

Paths containing spaces require the latter form.

** Caution **

The --chown feature is only supported in the Dockerfile used to build Linux containers, not in Windows containers. Since the concept of user and group ownership is not translated between Linux and Windows, use / etc / passwd and / etc / group to convert usernames and group names to identities. When used, this feature is limited to being executable only if it is a Linux OS-based container.

The `ʻADDinstruction copies the URL of a new file, directory, or remote file from and adds it to the image's file system with the path ``.

You can specify multiple <src> resources, but if they are files or directories, the path will be interpreted as relative to the source in the build context.

Each <src> can contain wildcards and collation is done using Go's filepath.Match rule. For example, to add all files starting with hom:

ADD hom* /mydir/

In the example below, ? Is replaced with any single character, such as home.txt.

ADD hom?.txt /mydir/

<dest> is an absolute path, or a relative path as seen from WORKDIR, and the source is copied into the destination container.

The following example uses a relative path to add test.txt to <WORKDIR> / relativeDir /:

ADD test.txt relativeDir/

This example uses an absolute path to add test.txt to / abstractDir /.

ADD test.txt /absoluteDir/

If you add files or directories that contain special characters (such as [ or ] ), you must escape these paths according to Go language rules so that they are not treated as matching patterns. There is. For example, to add a file named `ʻarr [0] .txt``, use:

ADD arr[[]0].txt /mydir/

With all new files, unless the optional --chown flag specifies a specific username, group name, or UID / GID combination to claim specific ownership of the added content. The directory is created with a UID and GID of 0. The form of the --chown flag allows you to use any combination of username and group name strings, or a direct integer UID and GID. If you specify a username without a group name or a UID without a GID, the same numeric UID as the GID is used. If a username or group name is specified, use the / etc / passwd and / etc / group files in the container's root file system to go from the name to the integer UID or GID. Each conversion is performed. The following example shows a valid definition of the --chown flag.

ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/

If the container root file system does not contain a / etc / passwd or / etc / group file and the username or group name is used with the --chown flag , The ```ADD`` operation causes the build to fail. The use of numeric IDs does not require lookups and is independent of the contents of the container root file system.

If <src> is the URL of a remote file, the destination has 600 privileges. If the remote file you get has an HTTP Last-Modified header, use the time stamp in that header to set the mtime for the destination file. However, like any other file processed during `ʻADD``, mtime is not included in determining if a file has changed and must update the cache.

** Caution **

If you pass a Dockerfile to STDIN ( docker build- <somefile) to build, the Dockerfile can only contain URL-based `ʻADDinstructions because there is no build context. I will. You can also pass the compressed archive via STDIN: ( docker build- <archive.tar.gz``). The Dockerfile at the root of the archive and the rest of the archive are used as the build context.

If the URL file is protected using authentication, then the `ʻADDinstruction does not support authentication, so use RUN wget, RUN curl``, or from within the container. You need to use another tool.

** Caution **

The first detected `ʻADDinstruction invalidates the cache of all subsequent instructions from the Dockerfile if the contents of are changed. This includes disabling the cache of the RUN`` instruction. For more information, see Dockerfile Best Practices Guide – Leverage Build Cache (https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache).

`ʻADD`` follows the rules below.

** Caution **

The directory itself is not copied, only its contents are copied.

  1. Whatever exists in the destination path
  2. Conflicting source tree contents are resolved with 2 priority for each file.

** Caution **

Whether a file is identified as a recognized compression format is based solely on the contents of the file, not the name of the file. For example, if an empty file happens to end with .tar.gz, it will not be recognized as a compressed file, no decompression error message will be generated, and the file will simply be copied to the destination.

COPY

COPY has two forms:

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

The latter form is required for paths that contain spaces.

** Caution **

The --chown feature is only supported in the Dockerfile used to build Linux containers, not in Windows containers. Since the concept of user and group ownership is not translated between Linux and Windows, use / etc / passwd and / etc / group to convert usernames and group names to IDs. To use. This feature is limited to being executable only if it is a Linux OS based container.

The COPY instruction copies a new file or directory from <src> and adds it to the container's file system with the path <dest>.

You can specify multiple <src> resources, but the file and directory paths are interpreted as relative to the source in the build context.

Each <src> can contain wildcards and collation is done using Go's filepath.Match rule. For example, to add all files starting with hom:

COPY hom* /mydir/

In the example below, ? Is replaced with any single character, such as home.txt.

COPY hom?.txt /mydir/

<dest> is an absolute path, or a path relative to WORKDIR, and the source is copied into the destination container.

The following example uses a relative path to add test.txt to <WORKDIR> / relativeDir /.

COPY test.txt relativeDir/

This example uses an absolute path to add test.txt to / abstractDir /.

COPY test.txt /absoluteDir/

If you copy files or directories that contain special characters (such as [ or ] ), follow Go language rules to escape these paths so that they are not treated as matching patterns. is needed. For example, to copy a file named `ʻarr [0] .txt``, use:

COPY arr[[]0].txt /mydir/

With all new files, unless the optional --chown flag specifies a specific username, group name, or UID / GID combination to claim specific ownership of the copied content. The directory is created with a UID and GID of 0. The form of the --chown flag allows you to use any combination of username and group name strings, or a direct integer UID and GID. If you specify a username without a group name or a UID without a GID, the same numeric UID as the GID is used. If a username or group name is specified, use the / etc / passwd and / etc / group files in the container's root file system to go from the name to the integer UID or GID. Each conversion is performed. The following example shows a valid definition of the --chown flag.

COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/

The container's root file system does not contain a / etc / passwd or / etc / group file and the username or group name is used with the --chown flag. If so, the build will fail with the COPY operation. The use of numeric IDs does not require lookups and is independent of the contents of the container root file system.

** Caution **

If you build using STDIN ( docker build- <somefile), you cannot use COPY because there is no build context.

Optionally COPY is a flag --from = <name> `that can be used to set the source location to the previous build stage (created with FROM .. AS ``) Accept `. Used in place of the user-submitted build context. If the build stage with the specified name is not found, an image with the same name will be used instead.

COPY follows the following rules:

** Caution **

The directory itself is not copied, only its contents are copied.

** Caution **

The first COPY instruction detected invalidates the cache of all subsequent instructions from the Dockerfile if the contents of <src> are changed. This includes disabling the cache of the RUN instruction. For more information, see Dockerfile Best Practices Guide – Leverage Build Cache (https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache).

ENTRYPOINT

`ʻENTRYPOINT`` has two forms:

The recommended format is the `ʻexec`` format:

ENTRYPOINT ["executable", "param1", "param2"]

Shell format:

ENTRYPOINT command param1 param2

You can use ʻENTRYPOINT`` to configure the container in which ʻexecutable`` is executed.

For example, the following example starts nginx with default content and listens on port 80.

$ docker run -i -t --rm -p 80:80 nginx

Command line arguments to docker run <image> are added after every element in the ʻexec`` format ʻENTRYPOINTand all elements specified using CMDOverwrite. This allows you to pass arguments to the entry point. That is, docker run -dpasses the -d argument to the entry point. You can override the `ʻENTRYPOINT instruction with the docker run --entrypoint flag.

The shell form no longer uses CMD or execution of command line arguments, but the disadvantage is that ENTRYPOINT`` is started as a subcommand of `` / bin / sh -c`` that does not pass a signal. there is. This means that `ʻexecutable`` is not receiving PID 1 for the container and does not receive a Unix signal. So executabledoes not receive SIGTERMfrom docker stop ``.

Only the last `ʻENTRYPOINT`` instruction in the Dockerfile is valid.

Example of ```ENTRYPOINT`` in Exec format

Can be modified using either form of CMD, after setting fairly stable default commands and arguments using ʻENTRYPOINT`` in the form ʻexec``. You can set additional default behaviors that are more likely.

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

When you run the container you will see that top is the only process.

$ docker run -it --rm --name test  top -H

top - 08:25:00 up  7:27,  0 users,  load average: 0.00, 0.01, 0.05
Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   2056668 total,  1616832 used,   439836 free,    99352 buffers
KiB Swap:  1441840 total,        0 used,  1441840 free.  1324440 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

You can use docker exec to examine the results further.

$ docker exec -it test ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  2.6  0.1  19752  2352 ?        Ss+  08:24   0:00 top -b -H
root         7  0.0  0.1  15572  2164 ?        R+   08:25   0:00 ps aux

You can also use the docker stop test to request that top be shut down gracefully.

The following Dockerfile shows how to run Apache in the foreground (that is, as PID 1) using `ʻENTRYPOINT``.

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

If you need to create a single ʻexecutable`` starter script, use the ʻexecand gosu commands to ensure that the last` ʻexecutable receives a Unix signal. You can be able to.

#!/usr/bin/env bash
set -e

if [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

Finally, if you need to perform additional cleanup (or communicate with other containers) on shutdown, or if you want to tune multiple ʻexecutable``s, the ʻENTRYPOINT`` script will signal a Unix signal. You need to make sure you send and receive to do some more work.

#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too

# USE the trap if you need to also do manual cleanup after the service is stopped,
#     or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM

# start service in background here
/usr/sbin/apachectl start

echo "[hit enter key to exit] or run 'docker stop <container>'"
read

# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop

echo "exited $0"

If you run this image with dockerrun -it --rm -p 80:80 --name test apache, you can see the container process with docker exec or docker top. Ask subsequent scripts to stop Apache.

$ docker exec -it test ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.1  0.0   4448   692 ?        Ss+  00:42   0:00 /bin/sh /run.sh 123 cmd cmd2
root        19  0.0  0.2  71304  4440 ?        Ss   00:42   0:00 /usr/sbin/apache2 -k start
www-data    20  0.2  0.2 360468  6004 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start
www-data    21  0.2  0.2 360468  6000 ?        Sl   00:42   0:00 /usr/sbin/apache2 -k start
root        81  0.0  0.1  15572  2140 ?        R+   00:44   0:00 ps aux

$ docker top test

PID                 USER                COMMAND
10035               root                {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054               root                /usr/sbin/apache2 -k start
10055               33                  /usr/sbin/apache2 -k start
10056               33                  /usr/sbin/apache2 -k start

$ /usr/bin/time docker stop test

test
real	0m 0.27s
user	0m 0.03s
sys	0m 0.03s

Caution

You can use --entrypoint to override the ʻENTRYPOINT`` setting, but this can only set `` binary`` to ʻexec ( sh -c`` Not used).

Caution

The `ʻexec format is parsed as a JSON array. That is, you must use double quotes ( ") before and after the word instead of single quotes ('``).

Unlike the shell form, the ʻexec`` form does not call a command shell. This means that normal shell processing is not done. For example, ʻENTRYPOINT [" echo "," $ HOME "] does not replace the variable in $ HOME. If shell processing is required, use the shell format or run the shell directly. Example: `ʻENTRYPOINT ["sh", "-c", "echo $ HOME"] If you run the shell directly using the `ʻexec`` format, as in the shell format, it is the shell, not Docker, that expands the environment variables.

Shell format ENTRYPOINT description example

If you specify a plain string for ʻENTRYPOINT``, it will be executed with `` / bin / sh -c``. This form uses shell processing to replace shell environment variables and ignores the `` CMD`` or [docker run](https://qiita.com/JhonnyBravo/items/eee5a91682f1d7c72f6e) command line arguments. Remember to start with ʻexecfor docker stop to correctly notify you of a long-running` ʻENTRYPOINT executable.

FROM ubuntu
ENTRYPOINT exec top -b

Running this image shows a single PID 1 process.

$ docker run -it --rm --name test top

Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
CPU:   5% usr   0% sys   0% nic  94% idle   0% io   0% irq   0% sirq
Load average: 0.08 0.03 0.05 2/98 6
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
    1     0 root     R     3164   0%   0% top -b

A clean exit with docker stop:

$ /usr/bin/time docker stop test

test
real	0m 0.20s
user	0m 0.02s
sys	0m 0.04s

If you forget to add ʻexec`` to the beginning of ʻENTRYPOINT``:

FROM ubuntu
ENTRYPOINT top -b
CMD --ignored-param1

You can then do that (name the next step).

$ docker run -it --name test top --ignored-param2

Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached
CPU:   9% usr   2% sys   0% nic  88% idle   0% io   0% irq   0% sirq
Load average: 0.01 0.02 0.05 2/101 7
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
    1     0 root     S     3168   0%   0% /bin/sh -c top -b cmd cmd2
    7     1 root     R     3164   0%   0% top -b

The output of top shows that the specified `ʻENTRYPOINT`` is not PID 1.

If you then run docker stop test, the container will not stop successfully. After the timeout, the stop command forces a SIGKILL to be sent.

$ docker exec -it test ps aux

PID   USER     COMMAND
    1 root     /bin/sh -c top -b cmd cmd2
    7 root     top -b
    8 root     ps aux

$ /usr/bin/time docker stop test

test
real	0m 10.19s
user	0m 0.04s
sys	0m 0.03s

Understand the interaction between CMD and ```ENTRYPOINT``

Both the CMD and the ENTRYPOINT`` instructions define the command to be executed when the container is run. Here are the rules that describe the collaboration between `` CMD`` and ENTRYPOINT``.

  1. The Dockerfile must specify at least one CMD or ```ENTRYPOINT`` command.
  2. If you want to use ʻexecutable`` in a container, you need to define ʻENTRYPOINT``.
  3. CMD should be used as a way to define the default arguments for the `ʻENTRYPOINT`` command or as a way to execute ad hoc commands in a container.
  4. Running the container with alternative arguments overrides CMD.

The following table shows the commands executed for various ʻENTRYPOINT`` / `CMD`` combinations.

No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”]
No CMD error, not allowed /bin/sh -c exec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry
CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry
CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry

** Caution **

If CMD is defined from the base image, setting ```ENTRYPOINTwill reset CMDto an empty value. You must define CMD`` in the current image to set the value in this scenario.

VOLUME

VOLUME ["/data"]

The VOLUME instruction creates a mount point with the specified name and marks it as holding an externally mounted volume from a native host or other container. The value is the JSON array VOLUME ["/ var / log /"], or VOLUME / var / log or It can be a plain string with multiple arguments, such as VOLUME / var / log / var / db. See Sharing directories through volumes (https://docs.docker.com/storage/volumes/) for more information, use cases, and mounting instructions through the Docker client.

The docker run command initializes a newly created volume with data that resides in the specified location in the base image. For example, consider the following Dockerfile snippet:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

This Dockerfile is a docker run that creates a new mount point on / myvol and puts a greeting file on the newly created volume. It will be the image to copy.

Precautions for specifying the volume

Note the following about Dockerfile volumes:

USER

USER <user>[:<group>]

Or

USER <UID>[:<GID>]

The ʻUSER`` instruction is the username (or UID) and optionally the user group (or UID) used when the image is executed and in the instructions following `` RUN``, CMD``, and ʻENTRYPOINT`` in the Dockerfile. Or GID).

When you specify a group of users, keep in mind that users only have the specified group membership. Other configured group memberships will be ignored.

** Warning **

If the user does not have a primary group, the image (or the next step) will run in the root group.

On Windows, you must first create a user if it is not a built-in account. This can be done using the netuser command, which is called as part of the Dockerfile.

FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick

WORKDIR

WORKDIR /path/to/workdir

The WORKDIR instruction is the working directory of all subsequent RUN, CMD, ENTRYPOINT``, `` COPY``, and ADDinstructions in the Dockerfile. Set. If WORKDIR`` does not exist, it will be created even if it is not used in subsequent Dockerfile instructions.

The WORKDIR instruction can be used multiple times in a Dockerfile. If a relative path is specified, it will be relative to the path of the previous WORKDIR instruction. For example:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

The output of the last pwd command in this Dockerfile will be / a / b / c.

The WORKDIR instruction can resolve environment variables previously set using ```ENV``. You can only use environment variables that are explicitly set in the Dockerfile. For example:

ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

The output of the last pwd command in this Dockerfile will be / path / $ DIRNAME.

ARG

ARG <name>[=<default value>]

The ʻARG`` command uses the --build-arg <varname> = <value> `flag when the user builds docker build Defines variables that can be passed to the builder with the command. If the user specifies a build argument that is not defined in the Dockerfile, the build will print a warning.

[Warning] One or more build-args [foo] were not consumed.

The Dockerfile may contain one or more `ʻARG`` instructions. For example, the following is a valid Dockerfile.

FROM busybox
ARG user1
ARG buildno
# ...

** Warning **

We do not recommend using build-time variables to pass sensitive information such as github keys, user credentials, etc. Build-time variable values are visible to all users of the image using the docker history command.

For a safe way to use confidential information when building an image, see Build an image using BuildKit (https://docs.docker.com/develop/develop-images/build_enhancements/#new- See docker-build-secret-information).

Default value

The `ʻARG`` instruction can optionally include a default value.

FROM busybox
ARG user1=someuser
ARG buildno=1
# ...

If the `ʻARG`` instruction has a default value and no value is passed at build time, the builder will use the default.

Scope

The definition of the `ʻARG`` variable takes effect from the line defined in the Dockerfile, not from the use of arguments on the command line or elsewhere. For example, consider the following Dockerfile.

FROM busybox
USER ${user:-some_user}
ARG user
USER $user
# ...

The user builds this file by calling the following command:

$ docker build --build-arg user=what_user .

The second line, ʻUSER``, evaluates to `` some_user`` because the user variable is defined in the next third line. The fourth line, ʻUSER, evaluates to what_userwhen the user is defined and the what_user value is passed to the command line. Before defined by the `ʻARG instruction, using a variable makes the string empty.

The ʻARG`` instruction goes out of scope at the end of the build stage in which it is defined. To use ʻarg in multiple stages, each stage must include the` ʻARG instruction.

FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS

FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS

Use of the `ʻARG`` variable

You can use the ʻARG`` or ʻENVinstruction to specify the variables available in the RUN instruction. Environment variables defined using the `ʻENV instruction always override theʻARG`` instruction with the same name. Consider this Dockerfile, which contains theʻENV and` ʻARG instructions.

FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=v1.0.0
RUN echo $CONT_IMG_VER

Next, suppose this image was created with the following command:

$ docker build --build-arg CONT_IMG_VER=v2.0.1 .

In this case, the RUN instruction uses v1.0.0 instead of the ARG`` setting passed by user: v2.0.1``. This behavior is similar to a shell script in which a variable in local scope overwrites a variable passed as an argument or a variable inherited from the environment from a definitional point of view.

Using the example above, but with a different ʻENV`` specification, you can create a more convenient interaction between the ʻARG and the` ʻENV instructions.

FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
RUN echo $CONT_IMG_VER

Unlike the ʻARG`` instruction, the ʻENVvalue is always kept in the built image. Consider a [docker build](https://qiita.com/JhonnyBravo/items/87976fe9de47ed58b8b1) without the --build-arg`` flag:

$ docker build .

Using this Dockerfile example, CONT_IMG_VER is still preserved in the image, but it is v1.0.0 because it is the default value set on line 3 by the ```ENV`` instruction. ..

Using the variable expansion technique in this example, you can pass arguments from the command line and You can use the `ʻENV`` instruction to persist them to the final image. Variable expansion is only supported with a limited combination of Dockerfile instructions.

Predefined `ʻARG``

Docker has a set of predefined ʻARG`` variables that you can use without the corresponding ʻARG`` instruction in your Dockerfile.

To use them, simply pass them on the command line with flags.

--build-arg <varname>=<value>

By default, these predefined variables are excluded from the output of docker history. Excluding the predefined variables reduces the risk of accidentally leaking sensitive credentials in the HTTP_PROXY variable.

Consider building the following Dockerfile using, for example, --build-arg HTTP_PROXY = http: //user:[email protected].

FROM ubuntu
RUN echo "Hello World"

In this case, the value of the HTTP_PROXY variable is not available in docker history and is not cached. If you change the location and the proxy server is changed to http://user:[email protected], there will be no cache misses in subsequent builds.

If you need to override this behavior, you can override it by adding the `ʻARG`` statement to your Dockerfile as follows:

FROM ubuntu
ARG HTTP_PROXY
RUN echo "Hello World"

When you build this Dockerfile, HTTP_PROXY is saved in docker history, and changing its value will invalidate the build cache.

Global Scope Automatic Platform ARG

This feature is only available if you are using the BuildKit backend.

Docker predefines a set of `ʻARGvariables with information about the platform of the node performing the build (build platform) and the platform of the resulting image (target platform). The target platform can be specified with the --platform`` flag in docker build.

The following `ʻARG`` variables are set automatically.

These arguments are defined in global scope and cannot be used automatically within the build stage or with the RUN command. To expose one of these arguments within the build stage, redefine it with no value.

For example:

FROM alpine
ARG TARGETPLATFORM
RUN echo "I'm building for $TARGETPLATFORM"

Impact on build cache

The ʻARG`` variable is not persisted to the image built like the ʻENV variable. However, the `ʻARG variable affects the build cache in a similar way. If your Dockerfile defines a ʻARG`` variable with a different value than in previous builds, you will get a cache miss`` on first use instead of that definition. In particular, all `` RUN`` instructions that follow the ʻARG instruction implicitly use the` ʻARG variable (as an environment variable) and can cause cache misses. All predefined ʻARG`` variables are cached unless there is a matching ʻARG`` statement in the Dockerfile.

For example, consider the following two Dockerfiles.

FROM ubuntu
ARG CONT_IMG_VER
RUN echo $CONT_IMG_VER
FROM ubuntu
ARG CONT_IMG_VER
RUN echo hello

If you specify --build-arg CONT_IMG_VER = <value> on the command line, the second line will not cause a cache miss in either case. The third line causes a cache miss. ```ARG CONT_IMG_VERidentifies the RUNline as the same as executing CONT_IMG_VER = echo hello, so it will be cached when `` is changed. A mistake will occur.

Consider another example on the same command line.

FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=$CONT_IMG_VER
RUN echo $CONT_IMG_VER

In this example, the cache miss occurs on line 3. A cache miss occurs because the value of the ʻENV`` variable references the ʻARG variable and that variable is modified on the command line. In this example, the `ʻENV command contains a value in the image.

If the ʻENV`` instruction overrides the ʻARG`` instruction with the same name, as in this Dockerfile:

FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=hello
RUN echo $CONT_IMG_VER

In the third line, the value of CONT_IMG_VER is a constant (hello), so no cache miss occurs. As a result, the environment variables and values used in RUN (line 4) do not change between builds.

ONBUILD

ONBUILD <INSTRUCTION>

The `ʻONBUILDinstruction adds a trigger instruction to the image that will be executed later when the image is used as the basis for another build. The trigger runs in the context of a downstream build, as if it was inserted immediately after the FROM`` instruction in the downstream Dockerfile.

Any build instruction can be registered as a trigger.

This is useful when building an image that will be used as a base for building other images. For example, an application build environment or a daemon that can be customized with your own configuration.

For example, if your image is a reusable Python application builder, you may need to add your application source code to a specific directory and then call your build script. You can't simply call ```ADDand RUN`` now because the source code of the application is not yet accessible and varies from build to application. You can also provide the boilerplate Dockerfile to the application developer and copy and paste it into your application, This is inefficient, error-prone, and mixed with application-specific code, making it difficult to update.

The solution is to use `ʻONBUILD`` to create a pre-instruction to be executed later in the next build stage.

The mechanism is as follows.

  1. When the `ʻONBUILD`` instruction occurs, the builder adds a trigger to the metadata of the image being built. Otherwise, the instruction has no effect on the current build.
  2. At the end of the build, a list of all triggers is saved under the `ʻOnBuildkey in the image manifest. They can be inspected with the docker inspect`` command.
  3. You can later use the FROM instruction to use the image as the basis for a new build. As part of the processing of the FROM instruction, the downstream builder looks for the ```ONBUILDtrigger and executes them in the same order as it was registered. If either trigger fails, the FROMinstruction will be aborted and the build will fail. If all triggers are successful, the FROM`` instruction is complete and the build continues normally.
  4. The trigger will be cleared from the final image after execution. In other words, they are not inherited by "grandchild" builds.

For example, you can add something like this:

ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src

** Warning **

ʻONBUILD ONBUILD`` is not allowed to chain ʻONBUILD`` instructions.

The> ʻONBUILD`` instruction may not trigger the FROM`` or `MAINTAINER`` instruction.

STOPSIGNAL

STOPSIGNAL signal

The STOPSIGNAL instruction sets the system call signal sent to the container to terminate. This signal should be a valid unsigned number that matches a position in the kernel's syscall table (for example, 9), or a signal name in the form of SIGNAME (for example, SIGKILL). I can.

HEALTHCHECK

The HEALTHCHECK instruction comes in two forms:

The HEALTHCHECK instruction tells Docker how to test the container to make sure it is still working. This allows you to detect cases where the web server is stuck in an infinite loop and cannot handle new connections, even though the server process is still running.

If the container has a health check specified, it has a health status in addition to the normal status. This status is initially "Starting". If you pass the health check, the health check will be "normal" (regardless of the previous state). After a certain number of consecutive failures, it becomes "abnormal".

The options that appear before CMD are:

The health check runs a few seconds after the container is first started, and then again a few seconds after each previous check is completed.

A check is considered unsuccessful if one run of the check takes longer than the timeout seconds.

Consecutive failures of health checks must be retried for the container to be considered abnormal.

The start period provides the container initialization time, which requires time for bootstrap. Probe failures during that period do not count towards the maximum number of retries. However, if the health check succeeds during the start period, the container is considered started and all consecutive failures are counted in the maximum number of retries.

There can only be one HEALTHCHECK instruction in a Dockerfile. If you list multiple items, only the last HEALTHCHECK will be valid.

The command after the CMD keyword is either a shell command (for example, HEALTHCHECK CMD / bin / check-running) or an ```exec array (like any other Dockerfile command). (See `ʻENTRYPOINT for more information)

The exit status of the command indicates the health status of the container. The valid values are:

For example, to check every 5 minutes and allow your web server to serve the main page of your site within 3 seconds:

HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

To help debug a failed probe, the output text (UTF-8 encoded) that the command writes to stdout or stderr is saved to health status and can be searched by docker inspect. .. Such output should be short (currently only the first 4096 bytes are stored).

When the container's health status changes, a health_status event is generated with the new status.

The HEALTHCHECK feature was added in Docker 1.12.

SHELL

SHELL ["executable", "parameters"]

You can use the SHELL instruction to override the default shell used for shell-style commands. The default shell for Linux is [" / bin / sh", "-c"]. The default shell for Windows is [" cmd "," / S "," / C "]. The SHELL instruction must be in JSON format in the Dockerfile.

The SHELL instruction is available on two commonly used native shells ( cmd and powershell) and an alternative shell that includes sh. Especially useful.

The SHELL instruction can be displayed multiple times. Each SHELL instruction overwrites all previous SHELL instructions and affects all subsequent instructions. Example:

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

The following instructions can be affected by the SHELL instruction when the shell format is used in the Dockerfile:

The following example is a common pattern found on Windows that can be rationalized using the SHELL instruction.

RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

The command called by docker looks like this:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

This is inefficient for two reasons. First, the unwanted cmd.exe command processor (also known as the shell) is being called. Second, each shell-style RUN instruction requires an additional powershell -command before the command.

You can use one of two mechanisms to make this more efficient. One is to use the JSON format of the RUN command, which looks like this:

RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]

The JSON format is clear and doesn't use the unnecessary cmd.exe, but double quotes and escapes require more detailed information. Another mechanism is to use the SHELL instruction and shell form. This makes the syntax more natural for Windows users, especially when combined with escape parser directives.

# escape=`

FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

Execution result:

PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
 ---> Running in 6fcdb6855ae2
 ---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in d0eef8386e97


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/28/2016  11:26 AM                Example


 ---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
 ---> Running in be6d8e63fe75
hello world
 ---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>

The SHELL instruction can also be used to change the way the shell behaves. For example, on Windows you can use SHELL cmd / S / C / V: ON | OFF to change the extended semantics of deferred environment variables.

The SHELL instruction is also available on Linux if you need an alternative shell such as zsh, csh, tcsh.

The SHELL feature was added in Docker 1.12.

External mounting function

This feature is only available if you are using the BuildKit backend.

docker build is enabled by using an external implementation of the builder with syntax directives, such as cache mounts, build secrets, ssh transfers, etc. Supports experimental features. See the BuildKit repository documentation (https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md) for these features.

Dockerfile description example

Here are some examples of Dockerfile syntax:

# Nginx
#
# VERSION               0.0.1

FROM      ubuntu
LABEL Description="This image is used to start the foobar executable" Vendor="ACME Products" Version="1.0"
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
# Firefox over VNC
#
# VERSION               0.3

FROM ubuntu

# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
RUN mkdir ~/.vnc
# Setup a password
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way, but it does the trick)
RUN bash -c 'echo "firefox" >> /.bashrc'

EXPOSE 5900
CMD    ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION               0.1

FROM ubuntu
RUN echo foo > bar
# Will output something like ===> 907ad6c2736f

FROM ubuntu
RUN echo moo > oink
# Will output something like ===> 695d7793cbe4

# You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.

Recommended Posts

Dockerfile reference Japanese translation
Docker mysql quick reference Japanese translation
sosreport Japanese translation
man systemd Japanese translation
streamlit explanation Japanese translation
streamlit tutorial Japanese translation
man systemd.service Japanese translation
man nftables Japanese translation
docker-compose --help Japanese translation
docker help Japanese translation
docker build --help Japanese translation
Japanese translation of sysstat manual
Japanese translation of Linux manual
docker run --help Japanese translation
Biopython Tutorial and Cookbook Japanese translation (4.3)
Biopython Tutorial and Cookbook Japanese translation (4.1)
Biopython Tutorial and Cookbook Japanese translation (4.5)
Biopython Tutorial and Cookbook Japanese translation (4.7)
Japanese translation of the man-db manual
Appropriate Japanese translation of pytorch tensor_tutorial
Biopython Tutorial and Cookbook Japanese translation (4.9)
Biopython Tutorial and Cookbook Japanese translation (4.6)
Japanese translation of the util-linux manual
Biopython Tutorial and Cookbook Japanese translation (4.2)
Biopython Tutorial and Cookbook Japanese translation (4.4)
Japanese translation of the iproute2 manual
Apache Spark Document Japanese Translation --Submitting Applications
Apache Spark Document Japanese Translation --Quick Start
Japanese translation of the LDP man-pages manual
Getting started: 30 seconds to Keras Japanese translation
Biopython Tutorial and Cookbook Japanese translation (Chapter 1, 2)
Japanese translation: PEP 20 --The Zen of Python