Docker: Advanced Concepts
1h 7m

In this lesson, you will learn how to create and use a Dockerfile to build Docker images.

We will discuss what Dockerfile and nano are, and how to create your own Dockerfile using nano.

You will look under the Docker hood to see what files make up the new image. You will edit the Dockerfile to get it ready for the hands-on exercises, and execute the file using bash.

For the hands-on, we will perform the following:
- Learn the FROM method to tell Docker we are going to work with the Ubuntu base image.
- Learn the MAINTAINER method where we will add the author/maintainer of the Dockerfile.
- Mount a data source on the host machine.
- Learn the EXPOSE method to open port 8080 for HTTP traffic


Hi and welcome to's video series on understanding Docker: Under the Hood. In this video, we're going to learn how to create and use a Dockerfile to build Docker images.

What is a Dockerfile?

A Dockerfile is simply a plain text file named Dockerfile with a capital D. That it has to be with a capital D that contains a script that will provide Docker with a template for building an image that you'd like to make available for yourself. Let's create a Dockerfile simply by using nano, that is, the terminal-based text editor.

Every Dockerfile must begin with the method FROM which is followed by the name of the base image from which you'd like to build your own image. At route this could be a complete Dockerfile. We'll save it by hitting control X and Y for yes. And now let's use that to build with "sudo docker build -t", any name you like so we'll call it stuff because I happen to like the name stuff and then we will point Docker to the directory where the Dockerfile lives. In this case it's the directory we have to be in right now. And the dot at the end of the line tells Docker that's where you should look. We'll hit enter and we have created an image called stuff based on the base image of Ubuntu.

Let's take a quick look at how Docker sees our new image. "sudo docker images" will list all the images currently associated with our system. And you see that stuff is included. It is tagged as latest because it's built on the Ubuntu, the latest version of Ubuntu available to the system. And it has an image ID of C4FF75 etc, which is identical to the image ID of Ubuntu itself which is also right below it, C4FF75 etc. Now the reason that the two images have the identical image ID is because nothing in our stuff image has actually changed from the original Ubuntu.

So let's make some change. Let's edit again the Dockerfile and we'll add a line. RUN which will run a command, and it will create a file called stuff in the root directory of our new image. Save that and let's again build the stuff image or a new version of the stuff image from the Dockerfile in the current directory that's been built. Now let's take another look at how Docker sees this image. Let's once again type "sudo docker images". This time stuff is all the way at the top.

It still has a tag of latest which was the same tag as the latest version of Ubuntu we used as its base but now it has an image ID of E2F25 etc. Whereas the Ubuntu latest image is still C4FF. So Docker has figured out that this stuff is in fact a new image, something has changed and it should be treated different than the base image upon which it was based.

Let's now run our new Docker image using run -i -t stuff, and we're going to run it using the bash shell. Let's list the files in the directories in the group directory and we see there is a file called stuff. Let's just to be complete LSL, a long list to give the full details of this file and we see it was created today just some moments ago.

A real Dockerfile example

Now let's take a look at an actual example of a Dockerfile script. First, as we've mentioned, you need the FROM method to tell Docker than we're going to work with the Ubuntu base image. Of course we have included a comment to describe what this line does as we will with every line in this script as you really should with every line, or at least every section of all code or script files that you create. Not only will it help other people reading your code, but as I can tell you from my own experience it often reminds me of what I was doing and what I was thinking when I wrote a script months before.

The next method is MAINTAINER where we add the author or current maintainer of this Dockerfile. It's not necessary, but it's good form to include this. The next method will run two commands to update the repo information that the container app-get facility currently has and then to install Apache 2 if Apache 2 is a package you'd like to have in your container.

Next, we will mount a data source, any files or directories that exist within the Dockerfile's path on the host machine. For some reason, Docker won't recognize files or directories that live above the directory where Dockerfile happens to be. Make sure, therefore, that if you want to mount a source from your host machine onto the Docker container, that this source lives below Dockerfile's path. Therefore, assuming that Dockerfile is in the home directory on your host machine or in the route of your host machine, you can add home/username/mydata to let's say var/www/html.

Finally, you might like to open port 8080 let's say for HTTP traffic on your container once it's up and running, and to do that we use the expose method.

About the Author
Learning Paths

David taught high school for twenty years, worked as a Linux system administrator for five years, and has been writing since he could hold a crayon between his fingers. His childhood bedroom wall has since been repainted.

Having worked directly with all kinds of technology, David derives great pleasure from completing projects that draw on as many tools from his toolkit as possible.

Besides being a Linux system administrator with a strong focus on virtualization and security tools, David writes technical documentation and user guides, and creates technology training videos.

His favorite technology tool is the one that should be just about ready for release tomorrow. Or Thursday.