Intro to Building Container Images with Dockerfiles

The basics

Tech Notes
8 min readApr 20, 2022


Let’s start building container images.

Introducing Dockerfiles

A Dockerfile is simply a plain text file full of instructions. We pass a Dockerfile to the docker image build command to assemble a container image.

FROM alpine:latest
LABEL maintainer=”Russ McKendrick <>”
LABEL description=”This example Dockerfile installs NGINX.”
RUN apk add --update nginx && \
rm -rf /var/cache/apk/* && \
mkdir -p /tmp/nginx/
COPY files/nginx.conf /etc/nginx/nginx.conf
COPY files/default.conf /etc/nginx/conf.d/default.conf
ADD files/html.tar.gz /usr/share/nginx/
EXPOSE 80/tcp
ENTRYPOINT [“nginx”]
CMD [“-g”, “daemon off;”]

Let’s touch upon Alpine Linux.

Alpine Linux is super tiny, efficient, secure Linux. It’s about 5MB. It has an extensive repository of packages, and it’s super secure thanks to the unofficial port of grsecurity/PaX, patched into its kernel. This port offers proactive protection against dozens of potential zero-day threats and other vulnerabilities.

Reviewing Dockerfiles in depth

Let’s take a look at the instructions we used in the preceding Dockerfile example. We will look at them in the order they appeared in:

  • FROM
  • RUN
  • COPY and ADD
  • Other Dockerfile instructions


The FROM instruction tells Docker which base you would like to use for your image. As we already mentioned, we are using Alpine Linux, so we simply have to state the name of the image and the release tag we wish to use. In our case, to use the latest official Alpine Linux image, we simply need to add alpine:latest.


The LABEL instruction can be used to add extra information to the image. This information can be anything from a version number to a description. It’s also recommended that you limit the number of labels you use. A good label structure will help others who will use our image later on.

Too many labels is inefficient. Use the label schema detailed at