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.
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 asRUN
) 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 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:
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 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.
$ {variable: -word}
indicates that if a variable is set, the result will be that value.
If the variable is not set, word
will be the result.$ {variable: + word}
indicates that word
will be the result if the variable is set, otherwise the result will be an empty string.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``.
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, namedtemp Exclude files and directories that start with. For example, a plain file/somedir/temporary.txt Is excluded and the directory/somedir/temp Is also excluded. |
*/*/temp* |
From a subdirectory two levels below the roottemp Exclude files and directories that start with. For example/somedir/subdir/temporary.txt Is excluded. |
temp? |
The name is temp+Excludes files and directories in the root directory that are a single character. For example/tempa When/tempb Is 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.
ʻARG`` is the only instruction that can precede `` FROM`` in the Dockerfile. See Understanding the interaction between
ʻARG and` `FROM
(Understanding the interaction between # arg- and -from-). FROM
can appear multiple times in a single Dockerfile to create multiple images or use one build stage as a dependency of another.
Just make a note of the last image ID output by commit
before the new FROM
instruction.
Each FROM
instruction clears all states created by the previous instruction.to the
FROMinstruction. This name can be used in subsequent
FROMand
COPY --from = 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
)
and
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:
RUN <command>
(shell format. The command is executed on the shell.
The default shell for Linux is / bin / sh -c
.
The default shell for Windows is cmd / S / C
) RUN [" executable "," param1 "," param2 "]` `(` ʻexec
format)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.
RUN
) rm
a file.
For systems with recent aufs versions (that is, you can set the dirperm1
mount option), docker will automatically try to fix the problem by mounting the layer with the diperm1
option. ..
See the aufs man page (https://github.com/sfjro/aufs3-linux/tree/aufs3.18/Documentation/filesystems/aufs) for more information on the dirperm1
option.
If your system doesn't support dirperm1
, Issue 783 (https://github.com/docker/docker/issues/783) describes a workaround.CMD
The CMD
instruction has three forms:
CMD [" executable", "param1", "param2"]
(` ʻexec`` format. This is the recommended format)CMD [" param1", "param2"]
(used as the default parameter to ```ENTRYPOINT``) CMD command param1 param2
(shell format)There can only be one CMD
instruction in a Dockerfile.
If you list multiple CMD
s, 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
withCMD
.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 <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
Example:
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
The `ʻENVinstruction allows you to set multiple
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
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 `ʻADD
instruction 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.
<src>
path must be in the context of the build.
The first step in the docker build is to send the context directory (and subdirectories) to the docker daemon, so `ʻADD ../something / something`` cannot be done.<src>
is a URL and <dest>
does not end with a trailing slash, the file will be downloaded from the URL and copied to <dest>
.<src>
is a URL and <dest>
ends with a trailing slash, the filename is inferred from the URL and the file is <dest> / <filename>
It will be downloaded to.
For example, `ʻADD http://example.com/foobar/creates the file
/ foobar. In this case, the URL must have an important path so that it can find the correct filename (
http://example.com`` does not work).<src>
is a directory, the entire contents of the directory containing the file system metadata will be copied.** Caution **
The directory itself is not copied, only its contents are copied.
<src>
is a local tar archive in a recognized compression format ( gzip
, bzip2
or xz
), it will be decompressed as a directory.
Resources from remote URLs are not unzipped.
When the directory is copied or unzipped, it behaves the same as tar -x
and the result is the following union. 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.
<src>
is another type of file, it will be copied separately with the metadata.
In this case, if <dest>
has a trailing slash /
, it is considered a directory and the contents of <src>
are <dest> / base (<src>. )
Written to.<src>
resources are specified, either directly or by using wildcards, <dest>
must be a directory and must end with a slash /
. there is.<dest>
does not end with a trailing slash, it is considered a regular file and the contents of <src>
are written to <dest>
.<dest>
does not exist, it will be created with all missing directories in the path.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 useCOPY
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
COPY
follows the following rules:
<src>
path must be in the context of the build.
You can't do COPY ../something / something
because the first step in dockerbuild
is to send the context directory (and subdirectories) to the docker daemon.<src>
is a directory, the entire contents of the directory containing the file system metadata will be copied.** Caution **
The directory itself is not copied, only its contents are copied.
<src>
is a file of a type other than a directory, it will be copied separately with the metadata.
In this case, if <dest>
has a trailing slash /
, it is considered a directory and the contents of <src>
are <dest> / base (<src>. )
Written to.<src>
resources are specified, either directly or by using wildcards, <dest>
must be a directory and must end with a slash /
. there is.<dest>
does not end with a trailing slash, it is considered a regular file and the contents of <src>
are written to <dest>
.<dest>
does not exist, it will be created with all missing directories in the path.** 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 theRUN
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 passes 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.
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.
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
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``.
CMD
or ```ENTRYPOINT`` command.ʻexecutable`` in a container, you need to define
ʻENTRYPOINT``. 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. 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.
Note the following about Dockerfile volumes:
C:
"
) instead of single quotation marks ('
). VOLUME
instruction does not support specifying the host-dir
parameter.
You must specify the mount point when you create or run the container.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).
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
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.
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.
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 = , so it will be cached when
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.
key in the image manifest. They can be inspected with the
docker inspect`` command. 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.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:
HEALTHCHECK [OPTIONS] CMD command
(Run a command inside the container to check the status of the container) HEALTHCHECK NONE
(disables health checks inherited from the base image)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:
--interval = DURATION
(default: 30s) --timeout = DURATION
(default: 30s) --start-period = DURATION
(default: 0s) --retries = N
(default: 3)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:
RUN
CMD
ENTRYPOINT
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.
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.
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