Link Search Menu Expand Document

Dockerfile Cheat Sheet

Dockerfile Examples

Installing packages

FROM debian:jessie

ENV DEBIAN_FRONTEND=noninteractive             # Always have this on Debian-based distros!

# Always
# - combine update + install to avoid apt caching issues!
# - disable recommends to get no extra packages!
# - clean lists afterwards
RUN apt-get update \
 && apt-get install -y --no-install-recommends python git
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

Copy files

COPY sourcefile.txt /app
COPY sourcefile.txt config.ini /app/           # Note the trailing slash on target with multiple files 
COPY dir1 /app

Adding users

RUN useradd jsmith -u 1001 -s /bin/bash

Defining work directories and environment

WORKDIR /home/jsmith/
ENV HOME /home/jsmith

Mounts

VOLUME ["/home"]

Opening ports

EXPOSE 22
EXPOSE 80

Start command

USER jsmith
WORKDIR /home/jsmith/
ENTRYPOINT bin/my-start-script.sh

Start command with parameters

ENTRYPOINT [ "script.sh", "param1", "param2"]            # using ENTRYPOINT command cannot be overridden, only parameters can be appended
CMD [ "script.sh", "param1", "param2"]                   # using CMD "docker run" can override command and parameters

Setting timezone

ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Using variables

RUN curl $JAR_DOWNLOAD
...
CMD java ${JAVA_OPTS} ...

Pass those variables using --build-arg JAR_DOWNLOAD=... --build-arg JAVA_OPTS="-D..."

For longer commands use CMD array syntax

CMD [ "java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", <...>]

Ensure pipe errors to break the build

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

Clear apt cache

RUN apt-get update \
  && apt-get install --no-install-recommends -y <packages> \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

Working with private registries

In Dockerfile use syntax with /

FROM <server>/<image>:<tag>

Define a variable registry in FROM clause and pass the hostname with --build-arg MY_REGISTRY=docker.example.com

ARG MY_REGISTRY=
FROM ${MY_REGISTRY}/myimage

Multi-stage Dockerfiles

Starting with Docker 17.05 you can do multi-stage builds by having multiple FROM commands in one Dockerfile

FROM image1
...

FROM image2
...

Above syntax example will automatically trigger two builds. Stages also can be named:

FROM image1 as stage1

and explicitely called on the CLI

docker build --target stage1 ...

Hardening Dockerfiles

Things you should do

  • Ensure there is a .dockerignore file in your base directory
  • Ensure there is a USER statement
  • Ensure there is a HEALTHCHECK statement (for non-k8s use cases)
  • Check FROM clause for trusted base images
  • Check curl/wget fetching from trusted domains only
  • Check your base image limits typical package managers (Python, Node, Maven…) to trusted repositories

In the end: firewall your build environment to avoid all unintended internet access