An Intro Guide to Unmistifying the Dockerfile

Gabriel Pulga
4 min readMar 4, 2021

Where it all begins?

Supposing I have a simple goal of running a container with Ubuntu and Java inside.

There are two possible outcomes to solve this problem.

  1. Writing a Dockerfile with the necessary instructions and creating a container from it.
  2. Using docker run so it runs the given container for us.

But, what does the command docker run do? It downloads an image from Docker Hub. And how was that image generated?

That’s right, with a Dockerfile made by someone else.

What is the Dockerfile?

The dockerfile is nothing more than a means to creating our own images.

Docker can build images automatically by reading the instructions from a Dockerfile.

A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.

Using docker build users can create an automated build that executes several command-line instructions in succession.

In other words, it’s a recipe to build a container.

The difference between an Image and a Container

An image is a representation of how a container will be built.

Because of this, we can’t run or initialize images, we can only do this with containers.

What needs to be understood is this : we write a Dockerfile, build an image from it using docker build and then create and run the given container with the command docker run.

They work together like a means to an end.

Creating a Container

So I picked a folder in my computer and created a file called Dockerfile. In it, I added the following line :

FROM ubuntu:18.04

By doing this, I started the proccess of creating an image.

I then opened my terminal, cd’d my way into the given folder and executed the command docker build . (with the dot).

Docker then proceeded to build the image from the file.

When the proccess ended, I executed the command docker image ls to see a list of the images recently built in my local machine, and there it was my very own image ready to be built as a container with the command docker run.

Giving instructions to the Dockerfile

FROM

This is a mandatory command used in all Dockerfiles to specify the starting point for the image that will be built.

So, if my wish is to build a Java-based image to build my container, I need to specify openjdk as its base, kind of like this :

FROM openjdk

But what if I want to build an image from absolute scratch? Well, that’s possible too :

FROM scratch

RUN

RUN is a pretty interesting command. It can be executed one or more times and it allows me to define which commands will be run in the layer creation step of the image.

For instance, we have the following Dockerfile :

FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install openjdk-8-jdk -y

When I execute docker build . , besides downloading Ubuntu 18.04 image to serve as a base to my own image, the creation proccess will also execute the commands I specified to update Ubuntu’s repositories through apt -get update.

It will also install Java 8 through apt-get install openjdk-8-jdk-y.

As a result, an image will be generated and from this image a container in which the two given commands will have been executed before it was even created.

So any container built from this image will have Ubuntu’s repository updated and Java 8 installed!

CMD

CMD and RUN are pretty similar.

We can pass parameters to them both in pretty much the same way.

The difference is that CMD is run after the container is built while RUN is executed in the image creation step of the process.

FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install openjdk-8-jdk -y
CMD touch hello-world

ADD and COPY

Pretty intuitive names, right?

ADD’s role is to make a copy of a file, directory or to download a URL from our local machine and get it inside of an image.

FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install openjdk-8-jdk -y
ADD host-file transferred-host-file

Funfact, if the host-file is a .tar, it will be decompressed automatically.

COPY behaves pretty much the same exact way, but unlike ADD, it doesn’t allow downloads.

WORKDIR

This command has the purpose of defining our work environment.

Basically, it specifies the standard directory that will be open when we execute the container and where the other commands such as CMD, RUN, ADD and COPY will be run.

Endnotes

The image creation proccess is of utmost importance for anyone that wishes to learn about Docker.

The key point of this article is understanding that through the Dockerfile we send several instructions in the form of commands as a means to an end.

More info about these commands can be found in the Dockerfile reference documentation.

Thank you.

--

--

Gabriel Pulga

DevOps/SRE Engineer from Brazil. Check out my github at @gabrielpulga