Dockerfile

From NovaOrdis Knowledge Base
Revision as of 23:24, 31 January 2018 by Ovidiu (talk | contribs) (→‎ENTRYPOINT)
Jump to navigation Jump to search

External

Internal

Overview

A Dockerfile is a plain text file that defines how a container should look at build time. It contains all the steps that are required to create the image.

Each line in the Dockerfile generates a new layer in the image. Multiple commands can be combined on a single line, to reduce the number of layers.

The Dockerfile is used as the argument of the docker build command.

Examples

Syntax

<instruction> <arguments>

Example

Dockerfile Example

Instructions

Instructions are also known as "directives", and they are part of a DSL.

FROM

https://docs.docker.com/engine/reference/builder/#from

A valid Dockerfile must start with a FROM instruction (ARG is the only instruction that can precede FROM). FROM specifies the base image upon which other layers are built. The identifier of the base image will appear as "Parent:" in the metadata of the resulting image.

FROM node:0.10

If the only Dockerfile instruction is FROM, the build command simply downloads the base image into the local registry, listing the image's repository and tag.

FROM can appear multiple times in a Dockerfile.

ARG

https://docs.docker.com/engine/reference/builder/#arg

COPY

https://docs.docker.com/engine/reference/builder/#copy
COPY <src> [src2 ...] <dest>

The COPY instruction copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest>. The source paths are relative to the build context.

Each occurrence of the COPY instruction creates a new layer in the final image.

This instruction is handled in a special manner relative to the build cache.

COPY should be preferred over ADD because it is more transparent.

Directory handling: if the <src> is a directory, its content will be recursively copied, but not the source directory itself. For example, if ./dir1 contains a file f.txt and a subdirectory ./dir2,

COPY ./dir1 /opt

A trailing slash does not make a difference.

ADD

https://docs.docker.com/engine/reference/builder/#add

Copies files from the local filesystem into the image.

ADD /something/something_else.conf $MY_PATH

This instruction is handled in a special manner relative to the build cache.

COPY should be preferred over ADD because it is more transparent.

ENTRYPOINT and CMD

Usually, there should be at least one ENTRYPOINT or CMD in the Dockerfile. If there isn't one, the executable launched when the container is run is specified by the last ancestor parent that has a ENTRYPOINT or a CMD specification - the value is inherited. If none of the ancestors specify an ENTRYPOINT/CMD and the current image does not specify one either, the Docker runtime produces this error message:

docker run <image>
docker: Error response from daemon: No command specified.

TODO Deplete Tmp.

ENTRYPOINT

https://docs.docker.com/engine/reference/builder/#entrypoint

The ENTRYPOINT instruction specifies the command and optionally the arguments to be used when a container is created from the image with docker run. ENTRYPOINT should be the preferred way of specifying the command to run when the container is intended to be used as executable, over the CMD instruction.

ENTRYPOINT has two forms:

  • The exec form ENTRYPOINT ["executable", "param1", "param2"]. This form is preferred.
  • The shell form.

How it is visible in the metadata?

CMD

https://docs.docker.com/engine/reference/builder/#cmd

How it is visible in the metadata?

USER

The user and group to run a container's processes as.

USER <user>[:group]
USER <UID>[:GID]

The USER instruction sets the user name or UID and optionally the user group or GID to use when running the image and for any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile.

If not specified, processes run as user "root" (UID 0).

Note that the value of the USER directive is alphanumeric, representing a user name, the name must be resolvable in the container, otherwise the container won't start:

docker: Error response from daemon: linux spec user: unable to find user blah: no matching entries in passwd file.

The constraint does not apply to UIDs, a container will start with any UID.

Also see:

Docker Security

ENV

Declares environment variable accessible to the processes in the container:

ENV SOMETHING "something else"

RUN

https://docs.docker.com/engine/reference/builder/#run

The RUN instruction will execute any command in a new layer on top of the current image, and commit results. The resulted committed image will be used for the next step in the Dockerfile. Layering RUN instructions and generating commits conforms to the core concepts of Docker where commits are cheap and containers can be created from any point in an image’s history, much like source control. However, in practice, it is a good idea to reduce the number of RUN commands - and layers they generate.

It has two forms:

  • Shell form:
RUN <command>
  • Exec form:
RUN ["executable", "param1", "param2", ...]

Running commands like yum in the Dockerfile is discouraged because it increases the time it takes for the build to finish. The alternative is to use base images that already have these updates applied.

WORKDIR

https://docs.docker.com/engine/reference/builder/#workdir

Changes the working directory within the context of the image being built, for the rest of the build instructions. If the WORKDIR doesn’t exist, it will be created. If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction.

The WORKDIR instruction can resolve environment variables previously set using ENV.

...
ENV SOMEDIR /some/dir
WORKDIR $SOMEDIR

MAINTAINER

It sets the "Author" field in the image metadata. It deprecated, use LABEL instead.

LABEL

Applies a label to the image.

LABEL "something"="something else" "other label"="some other content"

VOLUME

https://docs.docker.com/engine/reference/builder/#volume

The VOLUME instruction creates a mount point inside the container and marks it as holding an externally mounted volume from the native host. The docker run command initializes the newly created volume with any data that exists at the specified location in the base image. At runtime, the storage driver will be bypassed when written data into the volume, so the I/O will be performed at native speeds.

VOLUME /data
VOLUME [ "/data" ]

The native host directory cannot be declared in Dockerfile: it is by its nature host-dependent and it presence cannot be guaranteed, so to preserve portability, the native host mount point must be specified when creating the container with docker run --mount. The actual location of the volume on the native host is a directory whose path is returned by the corresponding "Source" entry in output of:

docker inspect -f '{{json .Mounts}}' <container-id>

For more details about data volumes see:

EXPOSE

https://docs.docker.com/engine/reference/builder/#expose

The 'EXPOSE' instruction serves as a hint (documentation) of the fact that the container listens on the specified ports at runtime, and those ports may be published. The instruction does not actually publish the port. Publishing is done with -p flag or -P flags in the docker run command.