Notes for DOCKERFILE learning and use

  • 2020-06-07 05:39:48
  • OfStack


Try to keep Dockerfile in an empty directory, and if you must have other files in the directory, use the.dockerignore file. Avoid installing unnecessary packages. Each container should focus on only one function point. Minimize the number of layers of mirrors. Multiple rows should be categorized. This makes it clear and straightforward, easy to read and review, and adds a space before each line break \. Have a clear understanding of the build cache.

Instructions notes


Dockerfile reference for the FROM instruction

Whenever possible, use the official mirror source as the base image of your mirror image. We recommend Debian Image as it is well managed and as a complete release package, but remains minimal in size (currently less than 150MB).

1. FROM must be line 1 other than the comment;
2. Multiple FROM statements can be used to create multiple image statements;

Dockerfile reference for the LABEL instruction

Dockerfile reference for the RUN instruction

The RUN statement is available in two formats:

1. RUN (the command is run in a shell - /bin/sh -c - shell form)
2. RUN ["executable", "param1", "param2"] (exec form)


Avoid using RUN ES71en-ES72en upgrade or ES74en-ES75en as many core packages of the base image will no longer be upgraded in unauthorized containers.
RUN ES78en-ES79en update and ES81en-ES82en install should be combined with one RUN statement. Such as:

  RUN apt-get update && apt-get install -y \
    package-bar \
    package-baz \

If you use update and install separately, executing multiple Dockerfile causes a caching problem that causes subsequent install statements to fail.
In addition, after executing the ES93en-ES94en statement, it is a good idea to finally add the statement removing the installation package to reduce the size of the image. Such as:

RUN apt-get update && apt-get install -y \
  aufs-tools \
  automake \
  build-essential \
 && rm -rf /var/lib/apt/lists/*

Note: The official Debian and Ubuntu images automatically execute "RUN ES101en-ES102en clean", so there is no need to explicitly delete instructions.

Pipe used

Many RUN commands need to use pipes, such as:

RUN wget -O - | wc -l > /number

Docker executes these commands using the /bin/ ES117en-ES118en interpreter, which evaluates only the return value of the last operation of the pipeline to determine whether the entire command was successful. In the above example, as long as the ES119en-ES120en command succeeds, a new image will be created even if the wget command fails. To avoid this, add ES122en-ES123en pipefail to the top of the statement & & . Such as:

RUN set -o pipefail && wget -O - | wc -l > /number

Note: Not all shell support the -ES134en pipefail option, such as the pattern shell: dash shell based on the mirror of Debian. In this case, we can use the RUN command in exec format to explicitly select shell to support the pipefail option. Such as:

RUN ["/bin/bash", "-c", "set -o pipefail && wget -O - | wc -l > /number"]


Dockerfile reference for the CMD instruction

The CMD statement differs from RUN in that RUN is run when build is mirrored, while CMD is run after build ends. An Dockerfile clock can have multiple RUN statements, although there can be multiple CMD statements, only the last CMD statement is executed. CMD statement format is:

CMD [“executable”, “param1”, “param2”…]


Dockerfile reference for the EXPOSE instruction

The EXPOSE directive specifies that the container listens on the linked port. Therefore, it is best to use commonly used, traditional application ports. For example, the Apache web server USES EXPOSE 80, etc.
To use for external links, you need to use the docker run command to map the container port to the host port.


Dockerfile reference for the ENV instruction
This is used to set the environment variable, which is then used by the RUM directive. You can also set the environment variable at container startup by docker run --env key=value. Such as:

RUN curl -SL$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress &&  ... 
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH


Dockerfile reference for the ADD instruction
Dockerfile reference for the COPY instruction

Although ADD and COPY have similar functions, it is generally recommended to use COPY. Because COPY is more transparent than ADD, COPY only supports copies from local files to containers, but ADD has a few other non-obvious features (such as native tar package unzipping and remote URL support). Therefore, the optimal use of ADD is for the local tar package to be automatically unzipped into the image. ADD rootfs.tar.xz /.

If there are multiple Dockerfile steps for working with different files, it is recommended that you separate COPY steps rather than copy them once. This ensures that the build cache for each step is only invalid if the corresponding file changes. Such as:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

The size of the mirror is important, so using ADD to get packages from remote URL is discouraged; You can use curl or wget instead. This way you can delete files that are no longer needed, such as the unzipped tar package, without adding additional layer to the image. For example, you should avoid using:

ADD /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all

It should be:

RUN mkdir -p /usr/src/things \
  && curl -SL \
  | tar -xJC /usr/src/things \
  && make -C /usr/src/things all

You should always use COPY for files and directories that do not need the ADD command tar package auto-unzip.


Dockerfile reference for the ENTRYPOINT instruction

Use ENTRYPOINT to set the main command for the image as if it were this command 1 when the image is run (and then use CMD as the default flag).
We use the s3cmd command as the main command for the mirror.

ENTRYPOINT ["s3cmd"]
CMD ["--help"]


Dockerfile reference for the VOLUME instruction

VOLUME directive 1 is commonly used for storage areas of databases, configuration storage, or files and directories created by docker containers.


Dockerfile reference for the USER instruction
If the service can run without privileges, then USER should be used to switch users to non-ES316en users. You can use the RUN command to create user groups and users such as:

RUN groupadd -r postgres && useradd -r -g postgres postgres

sudo should be avoided because of its unpredictable TTY and signal transfer features, which can cause problems. If you really want to use sudo like (root initializes daemon, not root), you can use gosu.


Dockerfile reference for the WORKDIR instruction

For Dockerfile content to be clear and reliable, it is always best to use absolute paths. Similarly, WORKDIR should be used instead of something like "cd... & & do-something "as that would make it difficult to read, find errors, and maintain.


Dockerfile reference for the ONBUILD instruction

Related articles: