Images From Containers
Start course
1h 38m

Welcome to Introduction to Docker! In this course, you'll learn the foundations of using Docker. You'll learn about images and containers, port mapping, Docker networks, volumes, tagging, and more. By the end of the course, you should be comfortable with the basic functionality of Docker.

Containers have existed in some form for a while now. However, it was Docker that brought them into the mainstream. And Docker containers have become synonymous with the word "container" because of their popularity. Docker containers have made it easier for many developers and operations teams to build, ship, and deploy their code.

While Docker containers may only be a transitional technology between virtual machines and unikernels (or something similar), they currently remain one of the more effective ways to ship code, which is why having an understanding of Docker has become almost a requirement for technical engineers.

Learning Objectives

  • You should understand what Docker is
  • You should understand how to create Docker images
  • You should understand how to map ports between Docker and the Host OS
  • You should understand the basics of Docker networking
  • You should understand how to use volumes for persistent storage
  • You should be able to tag images

Intended Audience

  • DevOps Engineer
  • Developer
  • Site Reliability Engineer
  • Operations Engineer


The course assets

Docker installation instructions

If you want to use Vagrant

The IDE used in the course

A Dockerfile reference

Tooling for the Go language used in the demos


Welcome back. We've seen how to create a basic image using a docker file. However, the docker file isn't the only way to create an image. You can also use the docker commit command to commit changes that you've made to an existing container. Now, my recommendation is that you should use the docker file when creating images.

When you use the docker file you get to treat that image as code in a sense. That means you can commit it to source control, you can easily share that docker file with other developers, and you can use it in automated testing to build the image, et cetera. So, while I recommend using the docker file, it's not the only option.

So I'm going to demonstrate how to use the docker commit command. Using the commit command allows you to save whatever changes you've made to a container. So I'm here at the bash prompt for the CentOS host and I'm currently the root user. If you're trying this along with me you'll need to be root or you'll need to use Sudu or maybe you'll add your user to the docker group, but inevitably you need to have root privileges.

So, there are no running containers as you can see here with the docker ps command and there aren't any stopped either, which shows because we're using the -a flag. There are a few images here. We have the greeting image, we have the hello world image, and the Ubuntu image. I'm going to use the Ubuntu as the base for this new image.

I want to create an image that has Python installed. Now, if this wasn't a demo I'd recommend that you use the official Python image. However, for the sake of this demo I'm going to install it in an Ubuntu container. Let's fire up the container based on the Ubuntu image and then run the ash binary. Okay great, we're at the bash prompt for the container and I want to show that Python is not installed.

So, I'm going to use the command which python and it returns nothing. So at a minimum the Python binary can't be found in any of the directories in the path environment variable. So, before we can install Python I need to update the apt cache and this is going to take a little while. So what I'll do is speed up the video and I'll meet ya back.

Okay, welcome back. Now let's install Python with apt and I will agree to the install. And again, this is gonna take a little while so I'm gonna speed this up too. Alright, with this done let's verify that it's installed. It seems that the binary exists and running Python with the version flag. Perfect, it shows that we have Python 2.

7. 12. Okay, we're now left with a container that has Python installed. The next step is to turn this into an image. So I'm going to exit out of the bash prompt, which will stop the container. If I list off the images, you can see that we still don't have our image. We do, however, have a container. The way that you turn a container into an image is with the commit command.

So let's run docker commit and then paste in the container ID and we'll pass along the tag for this image, which I'll call ubuntu_python. Notice how the image is now in the list of images. Here's the problem with this image. We didn't specify a new command for this image. So it's just going to use the default for the Ubuntu image, which in this case happens to be the bash command.

It's not because we ran the bash command, that's because whoever created the Ubuntu image used that as a default. So if we run a container based on this new image, since it's using bash as the default and I'm not using the interactive and a TTY for the pseudoterminal, it's just going to run the executable and then exit out and so what we're left with is a stopped container.

So, if the default command that you wanted to use was bash then you'd be all set. However, in this example what I'd rather do is use Python since we took the time to install it. So I'm going to remove this container that I just created. Okay, and I'm going to remove the image that we created so that we can commit a new one with a new command.

Perfect, okay now it's roughly the same command that we used before only this time we're going to use the change flag to change the command instruction. You can also change other instructions, however, for this demo. I'm only going to change the command. So the new command is going to instruct the container to use a python binary by default and that's going to pass in this c flag, which allows some arbitrary Python code to be executed and then the final element in this array here is the Python code that I want to execute.

And what this will do is just print out some text to standard out. Okay, now I need the container ID that this image will be based on and finally a tag for this image. Great, notice the image is in the list. Now if we create a container based on this image the default command should run that python binary, it's going to pass on the c flag, it's going to execute the code that I specified, which is import this.

So let's try that out. Perfect, there's our output. So everything's working. If we use the docker ps with the -a flag you can see that here it lists off a truncated version of the command that was executed. So, what have we learned in this lesson? We learned that docker allows you to create an image based on an existing container by using the commit command.

It also allows you to change instructions using the change flag. Alright, let's wrap up here. In the next lesson we're going to cover port mapping. So if you're ready to keep learning then let's get started in the next lesson.

About the Author
Learning Paths

Ben Lambert is a software engineer and was previously the lead author for DevOps and Microsoft Azure training content at Cloud Academy. His courses and learning paths covered Cloud Ecosystem technologies such as DC/OS, configuration management tools, and containers. As a software engineer, Ben’s experience includes building highly available web and mobile apps. When he’s not building software, he’s hiking, camping, or creating video games.