Docker build: Difference between revisions
Line 53: | Line 53: | ||
{{External|https://docs.docker.com/engine/reference/builder/#arg}} | {{External|https://docs.docker.com/engine/reference/builder/#arg}} | ||
Docker allows build-time variables, that can be initialized on <tt>docker build</tt> command line and used in the Dockerfile. This mechanism is useful for specifying environment specific configuration element (such as IP addresses, for example) | Docker allows build-time variables, that can be initialized on <tt>docker build</tt> command line and used in the Dockerfile. This mechanism is useful for specifying environment specific configuration element (such as IP addresses, for example). Built-time variables should not be used to pass sensitive information, such as password, since the values can be retrieved with [[docker history]] command. | ||
Using build-time variables is a two-step process: | Using build-time variables is a two-step process: |
Revision as of 00:09, 6 May 2018
External
Internal
Overview
docker build expects a Dockerfile and a context and uses the information provided to produce a Docker image.
docker build [options] <path>|<url>|-
The default location for the Dockerfile is the current directory, and the path is "."
The image such produced is placed in the local registry, using the repository name and the image tag provided with -t command line option. Note that if no -t option is use, the image will still be built, but it will be "dangling". For more details see -t command line option.
The Build Process
Starting with Docker 1.10, only RUN, COPY and ADD create layers.
As the Dockerfile instructions are evaluated in order, Docker inspects the build cache, looking for cached images that can be reused, instead of building a duplicate image from scratch. In matching commands to cached images, the following rules are followed:
- Starting with a parent image that is already in the cache, the next instruction is compared against all cached child images derived from that parent image, to see if one of them was built using the exact same instruction. If no such child image exists, the cache is invalidated.
- The literal instruction is used in comparison (presumably the cache maintains those instructions), with the exception of ADD and COPY.
- In case of ADD, COPY, the contents of the files to be copied are examined and a checksum is calculated for each file. The last-modified and last-accessed times of the file(s) are not considered in these checksums. The corresponding files in cache are also checksummed and the checksums are compared. If anything changed in the file - content or metadata - the cache is invalidated.
- RUN yum -y update commands require --no-cache=true to be effective.
- Once the cache is invalidated, all subsequent Dockerfile commands generate new images and the cache is not used.
The build cache can be explicitly invalidated with:
--no-cache=true
If a cached image was used, the build command output states that:
Step 2/5 : COPY ./loop /opt/loop ---> Using cache ---> 171da11cf0ef
The Build Context
The build context is a set of file located in a path, or at an URL, which are specified in the build command line. The commands in the Dockerfile are relative to the context.
The URL may refer to Git repositories, pre-package TAR files and plain text files.
.dockerignore
Build-Time Variables
Docker allows build-time variables, that can be initialized on docker build command line and used in the Dockerfile. This mechanism is useful for specifying environment specific configuration element (such as IP addresses, for example). Built-time variables should not be used to pass sensitive information, such as password, since the values can be retrieved with docker history command.
Using build-time variables is a two-step process:
1. The variables should be declared in Dockerfile with ARG as follows:
ARG=<name>[=<default value>]
The ARG instruction defines a variable that can be initialized at runtime, in the docker build command line, as shown below. One or more build-time variables may be defined, one per line. If user specifies a build argument that was not defined in the Dockerfile, the build outputs a warning.
It is not recommended to use build-time variables for passing secrets like github keys, user credentials etc. Build-time variable values are visible to any user of the image with the docker history command.
2. The variables should be initialized on docker build command line as follows:
docker build ... --build-arg VAR1=value1 --build-arg VAR2=value2 ...
Options
-t, --tag
Even if the option is named "tag", it actually specifies the target image repository URL, ignoring the registry host name - the image is always placed in the local registry. In one of its simplest variants, the URL can be just a tag, indeed. Most commonly, the URL contains the namespace and the repository name, or just the repository name. For more details about a repository URL, see: URL.
docker build -t novaordis/centos-loop:latest .
If no name/tag information is provided, there is no default: the image may be stored with no repository and no tag, just with an image ID. An "unnamed" images is called "dangling":
REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 4cfda3233bb6 5 seconds ago 204MB
Alternatively, if the only Dockerfile instruction is FROM, or ..., the name and the tag will be inferred from the base image.
If the name/tag combination already exists in the repository, the image they designate will be "unnamed" (dangled) and the new image that has just been built replaces it.
--rm
--rm=true
Remove intermediate containers after a successful build (default true).
-f
Instructs the build process to use a Dockerfile other than the ./Dockerfile.
docker build -f ./my.Dockerfile -t something .
--no-cache
Do not use the cache while building the image. See more here: The Build Process.
--build-arg
See Built-Time Variables above.
Multi-Stage Build
A more efficient replacement for the builder pattern.
The general syntax involves adding FROM additional times within the Dockerfile and naming build stages. Whichever is the last FROM statement is the final base image. To copy artifacts and outputs from intermediate images use COPY --from=<base_image_name>:
FROM something AS my_builld
# This results in a single layer image
FROM alpine:latest
COPY --from=my_builld ...