Dockerfile cheat sheet


DockerfileInstructions are summarized.

  • Docker version: v19.03

Simplified chart


Acquire by specifying the base image. The first line is this command. Specify an image from Docker Hub or a private Docker repository.

  • No tag specified: latestpull


FROM centos:7.7.1908
ENTRYPOINT [ "/bin/bash" ]
$ docker image build --file Dockerfile -t testrepo:test .
$ docker image ls --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
testrepo test 204MB # < -The image created this time
centos 7.7.1908 204MB # < -Base image
  • Tag specified: Pull with specified tag, basically should be specified


FROM centos
ENTRYPOINT ["/bin/bash"]
$ docker image build --file Dockerfile -t testrepo:test .
$ docker image ls --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
Testrepo Test 220MB # <- created this time the image
Centos Latest 220MB # <- based image


Execute the specified command. It is described later in Tips, but should be described together as much as possible.


FROM centos:8
RUN yum install -y httpd iproute && \
echo "Test" > /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/httpd"]


Specifies the command to be executed when the container is started. An image that is written once at the end of the Dockerfile.


FROM centos:8ENTRYPOINT ["df"]
CMD ["-H", "."]

Specify the command to be specified by separating each space with a comma. For example go run main.go, if you want to specify:


ENTRYPOINT ["go", "run", "main.go"]

Difference between ENTRYPOINT and CMD

ENTRYPOINTIs always executed as is,CMDcan be overwritten by specifying an argument when starting the container. Taking advantage of this property, you can write the ENTRYPOINTcommand part CMDand the command option part. Assuming that the image is built with the above Dockerfile, the difference between the concrete execution results when starting the container with arguments and when starting the container without arguments is shown below.

  • No argument: df -H .is executed.
$ docker run override_test
Filesystem Size Used Avail Use% Mounted on
overlay 63G 2.1G 58G 4% /
  • With argument ( --help): df --helpis executed. You can see that the CMD part is overwritten by the options specified on the command line.
$ docker run docker_test --help
Usage: df [OPTION]... [FILE]...
Show information about the file system on which each FILE resides,
or all file systems by default.
Mandatory arguments to long options are mandatory for short options too.
-a, --all include pseudo, duplicate, inaccessible file systems


Copy a file or directory from the host machine into the container. Directory structure of host machine

├── Dockerfile
├── copied
│ ├── subfile.txt
│ └── subfile2.txt
└── copyfile.txt


FROM centos:latestRUN mkdir  -p / app
# file unit
COPY ./copyfile.txt / app
# directory * It is necessary to specify the directory name of the copy destination.
COPY ./copydir / app / subdir
$ docker image build --file Dockerfile -t centos:copytest .
$ docker container run centos:copytest ls -ltR /app
total 8
drwxr-xr-x 2 root root 4096 Jan 12 13:27 subdir
-rw-r--r-- 1 root root 6 Jan 12 13:18 copyfile.txt
total 4
-rw-r--r-- 1 root root 0 Jan 12 13:25 subfile2.txt
-rw-r--r-- 1 root root 8 Jan 12 13:19 subfile.txt


COPYSimilarly, copy the file from the host machine into the container. (Above Dockerfile of COPYthe ADDwill be the same result as) However, ADDwhen you use the, if the copy file is a compressed file, will be performed automatically decompress.


FROM centos:8RUN mkdir  -p /app
# addtest.tar is a compressed file of
copydir ADD ./addtest.tar/app


$ docker image build --file add/Dockerfile -t centos:addtest .
$ docker container run centos:addtest ls -lR /app
total 4
drwxr-xr-x 2 501 games 4096 Jan 12 13:25 copydir
total 4
-rw-r--r-- 1 501 games 8 Jan 12 13:19 subfile.txt
-rw-r--r-- 1 501 games 0 Jan 12 13:25 subfile2.txt
# There is no tar file itself and decompression Existed

ef COPY the case of


$ docker container run testrepo:copy ls -lR /app
total 4
-rw-r--r-- 1 root root 177 Jan 12 13:31 addtest.tar # leave the compressed file

Separation from COPY

  • When copying is simply performed => COPY
  • To copy and decompress => ADD


Add environment variables to the execution container.


FROM centos:8
ENV NEW_ENV='env-value'
ENTRYPOINT ["/bin/bash"]


$ docker image build --file Dockerfile -t centos:envtest .
$ docker container run -it centos:envtest
[root@de6dc0f2577e /]# env
NEW_ENV=env-value # fileで追加した環境変数


Put the specified port in the LISTEN state.


FROM python:3.8-slim-busterCOPY . /
RUN pip install -r /app/requirements.txt
ENTRYPOINT [ "gunicorn", "flask_app:app" ]
CMD [ "-c", "/app/config/" ]


$ docker image build --file Dockerfile -t python:flask .
$ docker container run --name exposetest python:flask
$ docker container ps --format "table {{.Image}}\t{{.Ports}}"
flask 9876/tcp exposetest
a2556b3a812 worktest
# LISTENED port number is displayed in PORTS


Change working directory. In Dockerfilecd


FROM centos:8
RUN mkdir -p /test
RUN echo "before workdir" > before.txt
RUN echo "after workdir" > after.txt
ENTRYPOINT ["/bin/bash"]


$ docker image build --file Dockerfile -t centos: workdir . 
$ docker container run -it --name workdirtest centos: workdir
[ root @ 4cd5accab742 test ] # pwd
/ test # The last WORKDIR path is the base path for starting the container to become
[ root Atto 4Cd5accab742 Test ] # Ls .. | Grep before
Before.Txt # before the presence in the root directory that you have created before WORKDIR
[ root Atto 4Cd5accab742 Test ] . # Ls
After.Txt # for after is created after WORKDIR Exists in the / test directory


Light weight with multi-stage build

A multi-stage build is like a technique to reduce the weight of the final finished image. As an example, Golet's compare the image size between when the application is applied with multi-stage build and when it is not.

  • No multi-stage build


FROM golang:1.13-alpine
COPY ./main.go ./
RUN go build -o /app ./main.go
  • Multi-stage build available


# 1st step (build) 
FROM golang: 1.13-alpine as builder
COPY ./main.go ./
RUN go build -o / app ./main.go
# Second stage (this is the completed image)
# Select a lightweight image that meets the minimum requirements for the base
FROM alpine: 3.11
# Copy the required items from the first stage container
COPY --from = builder / app.
ENTRYPOINT [" ./app "]
  • Check size


REPOSITORY     TAG                 SIZE
golang nonmultistage 361MB
golang multistage 7.6MB # overwhelmingly light

Combine instructions as much as possible

An image cache is built for each Dockerfile instruction. Minimizing this number of image cache layers is considered a best practice, which can result in lighter weight and faster builds. Specifically, perform the following actions.

  • RUN instructions are connected by “backslash + &&”
  • Keep COPY / ADD instructions as small as possible

In particular, RUNthere is a problem with the cache at the time of build, yum updateand if you do not connect them with yum installthe &&word , you may get stuck. (The cache is not described in this article.)

URL can be specified in ADD instruction, but it is not written

Use curlor when retrieving resources from a URL in order to reduce the number of layers and reduce the image weight wget.

Example ( excerpt from Best practices )


# Good
RUN mkdir -p /usr/src/things \
&& curl -SL \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
# Bad
ADD /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all


 by the author.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store



DevOps Consultant. I’m strongly focused on automation, security, and reliability.