Dockerfile¶
A Dockerfile is a recipe file that can be used to create a docker image out of it as:
docker build <dir with Dockerfile> -t <name>
A Dockerfile contains a set of instructions, each of which constitutes a new layer on top of the previous one.
Useful instructions in a dockerfile are:
FROM <base image> # base image
ADD <file or dir> [<dst>] # copy files or directories to the image
RUN <cmd> # execute command in the image
ENV <var> # define environment variable
CMD <cmd> # command to be executed when the container starts
Other useful instructions are:
WORKDIR <dir> # set a working directory
VOLUME <path> # create a mount point for external volumes
EXPOSE <port> # expose a particular port in the container
USER <uid> # change container user
The user in the container is root by default. You can use any other
user, but it must exits in the host OS.
Many services use user 999 as default.
Example¶
Example of a Dockerfile:
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
Multi-stage¶
Multi-Stage Dockerfiles allow to create images on every stage, and copy files from earlier stages to keep final images small.
E.g.:
# stage - 1
FROM ubuntu AS buildstep
RUN apt-get update && apt-get install -y build-essential gcc
COPY hello.c /app/hello.c
WORKDIR /app
RUN gcc -o hello hello.c && chmod +x hello
# stage - 2
FROM ubuntu
RUN mkdir -p /usr/src/app/
WORKDIR /usr/src/app
COPY --from=buildstep /app/hello ./hello
COPY ./start.sh ./start.sh
ENV INITSYSTEM=on
CMD ["bash", "/usr/src/app/start.sh"]
Tips¶
Limit the number of instructions¶
Each instruction in a Dockerfile constitutes a new layer. For this reason, it is often recommended to combine items that have the same instruction (if that makes sense). E.g. instead of
RUN apt-get update
RUN apt-get install -y git
in two lines, they can be combined into a single line as:
RUN apt-get update && apt-get install -y git
In the RUN case, it also has other benefits, because the first
instruction is cached, it might be that the second gets and out of date
version of the packages.
Keep your image small¶
Try to use small base images (e.g. alpine) or slim versions (e.g. Debian bullseye-slim).
Moreover, try to remove any extra stuff you added and it is not required. E.g.:
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y \
build-essential \
git \
&& rm -rf /var/lib/apt/lists/*