DevOps Pills - Dockerfile Cheat Sheet

January 9, 2019

Common Docker Instructions


Set the base image. Every Dockerfile have this instruction at the top.

The syntax is:

FROM <image>, or FROM <image>:<tag>, or FROM <image>@<digest>

example: FROM alpine:latest

  • if you skip the tag or digest Docker will assume the “latest tag”

  • if the tag or digest that you provide cannot be found Docker will throw an error during the build


Set the author field of the generated image.

  • can be your name, username, email, or whatever you would like
  • it is a good practice to place it on the top of the file, just after the FROM instruction
  • it will not make any changes to the generated image

The syntax is:

MAINTAINER author_name_or_whatever

example: MAINTAINER @lucasepe


Sets a working directory for any CMD, RUN, ENTRYPOINT, COPY, and ADD instructions that comes after it in the Dockerfile.

The syntax is:

WORKDIR <path>

example: WORKDIR /home/myusername/myapp/

  • can have multiple WORKDIR instructions in one Dockerfile
  • if a relative path is provided; it will be relative to the path of the previous WORKDIR instruction


Copy files or directories from <source path or URL> and add them to the file system of the container at <destination path>.

The syntax is:

COPY <source path or URL> <destination path>

If the source path ends with a trailing slash, it will be considered a directory - its contents will be copied into the destination path - ⚠️ the destination directory must already exists

COPY (hints)

  • the <destination directory> can be an absolute path or a path relative to the directory specific by the WORKDIR instruction

  • the files created in the image will always be with UID:0 and GID:0

COPY [--chown=<user>:<group>] \
   <source path or URL> <destination path>

example: COPY --chown=username:groupname target/libs/*.jar /path/to/libs/

The –chown feature is only supported on Dockerfiles used to build Linux containers, and will not work on Windows container.


Execute a single or more commands in a new layer and then commit the results.

The syntax is:

RUN <command>

example: RUN mkdir -p path/to/libs

The command is run in a shell default is /bin/sh -c on Linux or cmd /S /C on Windows.

  • executed at build time
  • executed in the same order they appear
  • each RUN instruction creates a new layer in the image

RUN (hints)

💡 You can split long or complex RUN statements on multiple lines separating them with a backslash.

RUN set -x \
   && apk add --no-cache \
       openjdk8="$JAVA_ALPINE_VERSION" \
   && [ "$JAVA_HOME" = "$(docker-java-home)" ] \
   && apk add --no-cache bash \
   && adduser -D -u 1000 -s /bin/bash technology
  • Dockerfile will be more readable and easier to maintain


Informs Docker that the container listens on the specified network ports at runtime.

  • equivalent to the docker run –expose command-line option

The syntax is:

EXPOSE port_number
  • it does not set up any networking properties

You can think of it more like a runtime configuration option that is explicitly stated in your Dockerfile.

EXPOSE (hints)

⚠️ EXPOSE will not allow communication via the defined ports to containers outside of the same network or to the host machine.

To allow this to happen you need to publish the ports.

  • use the –publish flag to publish a range of ports
docker run -p 8080:8080/tcp my_app
  • use the –publish-all flag to publish all of the exposed ports at once
docker run -P my_app


Create a mount point with the specified name.

  • to be able to save (persist) data
  • to share data between containers

The syntax is:

VOLUME path1 path2 ..., or VOLUME ["path1", "path2", ...]
  • running your container all the files saved to pathX will be available for other containers for sharing

VOLUME (hints)

💡 We can also create volumes using the docker volume create command.

docker volume create --name my-vol

Which we can then attach to a container at run-time:

docker run -d -v my-vol:/data IMAGE 
  • mount the volume my-vol at /data inside the container

How to mount a specific directory from the host into a container

docker run -v /home/username/data:/data IMAGE
  • any files already existing in the /home/username/data directory will be available inside the container


Sets the environment variable <key> to the value <value>.

First syntax:

ENV key val

example: ENV LANG C.UTF-8

Second syntax:

ENV key=val key2=val2  

example: ENV JAVA_HOME="/usr/lib/jvm/java-1.8-openjdk"

  • this form allows setting multiple environment variables at once
  • if you need to provide spaces in the values, you will need to use quotes
  • if you need quotes in the values, use backslashes

ENV (hints)

  • the environment variables set using ENV will persist when a container is run from the resulting image

  • you can view the ENV values using the docker inspect command

  • the ENV values can also be overridden just before the start of the container, using docker run –env <key>=<value>


Specify a command that is executed when the container is launched (docker run).

The syntax is:

CMD ["executable","param1","param2"]

example: CMD [ "java", "-jar", "app.jar" ]

  • CMD is a runtime instruction while RUN is a build-time instruction


Specifies a command that will always be executed when the container starts.

😱 whaat? sounds like CMD instruction!

Differences between CMD and ENTRYPOINT

Docker has a default ENTRYPOINT which is /bin/sh -c but does not have a default CMD.

  • CMD specifies the arguments that will be sent to the ENTRYPOINT

To change default shell in your image:

ENTRYPOINT ["/bin/bash"]


  • ENTRYPOINT sets the default application that is used every time we run the container
  • ENTRYPOINT should be defined when using the container as an executable
  • CMD is a clean way to define default arguments for the command in ENTRYPOINT
  • CMD will be overridden when running the container with alternative arguments
  • ENTRYPOINT can be overridden starting the container using docker run –entrypoint parameter