A Dockerfile Example

This article is mainly focusing on how to build a docker image using Dockerfile. It’s very simple but can be seen as a minimum viable knowledge (MVK) on using Dockerfile. And since the simpleness, you can focus on the main idea of how Dockerfile works, instead of complicated code which no longer help in another project.

The example is from docker’s official documents, building a robot whale from a public image, but some explanation is added in this article.

Create your Dockerfile

If you want docker to build an image from Dockerfile, you need to tell where the file is. For convenience, we’d better to make a new directory and put only one Dockerfile in it.

mkdir docker-projects
cd docker-projects
touch Dockerfile

Write command line in Dockerfile

There are only three lines we need to write in this Dockerfile. However, from my experience on exploring docker, this three lines are very representative. You probably will use them in any other project.

FROM docker/whalesay:latest
RUN apt-get -y update && apt-get install -y fortunes
CMD /usr/games/fortune -a | cowsay

The first line tell docker which image the new project is based. If your machine has the image locally, docker will set it up and use it. If not, docker will pull the image from docker hub.

The 2nd line tell the container run apt-get command, which is set up from the first line. And if you have deployed something, like rails, on ubuntu server, you know this command is regular. As well, you can know that docker/whalesay is based on ubuntu.

The 3rd line, as the last line, uses CMD as final hit. usr/games/fortune must be a bin file that can run as a command. When docker reach the last line, it’ll run this bin file, and you’ll see the output. And I guess this CMD define the action that docker do when docker run <image name> is implemented.

Finally, save this file and turn to the terminal.

Build image

Now, we are ready to build the image. Run:

docker build -t docker-whale .

And you’ll see a lot of messages come out. Let’s explain them.

First, look at the command.

docker build tell docker that we want it to build something. And -t option help us add a tag to the image, namely, latest. The forth part, docker-whale will be the new image’s name. Finally, don’t forget the point, it declare that Dockerfile is in current directory.

Next, let’s look on the information after the build command

❯ docker build -t docker-whale .
Sending build context to Docker daemon 2.048 kB
Step 1/3 : FROM docker/whalesay:latest
latest: Pulling from docker/whalesay
e190868d63f8: Pull complete
#...
8eed3712d2cf: Pull complete
Digest: sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b
Status: Downloaded newer image for docker/whalesay:latest
---> 6b362a9f73eb
Step 2/3 : RUN apt-get -y update && apt-get install -y fortunes
---> Running in a72153fddc36
Ign http://archive.ubuntu.com trusty InRelease
Get:1 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB]
#...
Setting up fortunes (1:1.99.1-7) ...
Processing triggers for libc-bin (2.19-0ubuntu6.6) ...
---> fa0d57a63ee3
Removing intermediate container a72153fddc36
Step 3/3 : CMD /usr/games/fortune -a | cowsay
---> Running in 91977f13a897
---> 10aa7a8b7ba0
Removing intermediate container 91977f13a897
Successfully built 10aa7a8b7ba0

The line start with Sending build context shows the Dockerfile is sent to Docker daemon, so that it can be implemented. When this step was finished, docker will docker take action as you told him in Dockerfile.

As a result, you can see Step 1/3:, followed by the codes which are exactly the same as you wrote in Dockerfile, and other steps have the similar output as well.

As we have said before, the each line in Dockerfile will implement something, and now you see the result through the output. And a detailed knowledge is that after the image has been downloaded to local machine, docker set it up in an intermediate container, and run following step in that container. To prove that, you can read the message just after the Step 2, which says Running in a72153fddc36 . As the document of docker show, this long code represent an intermediate container’s id. Then, when this step has been finished, the intermediate would be removed, just as the message before Step 3 shows. And another intermediate container will created when docker turns to next step. You can read it from the messages as well.

Finally, a message saying successfully built come out, followed by a new container id, which is exactly the id of your new image’s container.

Run the image

After successfully build your image, you will see it appears in docker images.

Then, simply run this image with:

docker run docker-whale

It generate a whale saying something.

Recognize the pattern

From this example, I can tell the every step will appear again and again in other docker projects. Let’s recognize the pattern so that we can know what other docker project author is doing.

  1. Write Dockerfile with image base, namely, using From, and other commands that building ubuntu environment, etc.
  2. Build the image by using docker build.
  3. Run the image by using docker run