Exercise 2: Docker images¶
This exercise starts off with exploring a Docker image’s history and ends with your first Docker image on the Docker Hub. Let’s get started!
Join the chat room for this exericse: https://gitter.im/atbaker/oscon-exercise-2
Remember, you will need to reference the Docker documentation to work through these exercises.
The next two exercises deal with Dockerizing some Python apps, but you don’t need to know much Python to complete them.
Anatomy of an image¶
Docker images are just portable, saved states of Docker containers. Images are how you move your Dockerized applications from your development machine to the world.
Let’s examine one of the Docker images we used in the last exercise,
atbaker/nginx-example. Look at the commands used to create that image with the
docker history command.
docker history command uses this basic syntax:
docker history IMAGE_NAME
If you’re curious about how Docker images work, you can read more about it here: https://docs.docker.com/introduction/understanding-docker/#how-does-a-docker-image-work
Meet our Flask app¶
Flask is a lightweight Python web framework. In this exercise, we’re going to add a
Dockerfile to a Flask application to help us build a Docker image for it.
I have already written the Flask app for you, so you should start by cloning the git repository at https://github.com/atbaker/docker-flask. You can do this with
git clone if you have git installed, or by clicking the “Download ZIP” button on GitHub.
If you want, you can run this app through your laptop’s native Python installation first just to see what it looks like. Run
sudo pip install -r requirements.txt and then run
You should then be able to open a web browser, go to http://localhost:5000, and see the message
Hello! I am a Flask application.
This is totally optional - but some people like to see what the app’s supposed to do before they try to Dockerize it.
Creating a Dockerfile¶
A Dockerfile is a special file in your source code that tells Docker how to build an image for your application.
Most commands in a given Dockerfile are used to install dependencies for your application, like OS packages and programming language libraries.
Other commands specify default
docker run options for containers created from that image, like the default command that should be run in that container or the default ports to expose to the host.
Every Dockerfile needs a base image to build off of. While you can choose plain Linux distributions (like Ubunutu) as your base image, it’s usually more efficient to pick a base image which already has some of your application’s dependencies installed.
Docker maintains a library of official base images for various programming languages and server applications that save you the trouble of installing them manually.
Find the official Python Docker image in the list of official base images linked above. Read through the “How to use this image” section.
Following the instructions on the official Python image, complete the Dockerfile in your clone of the atbaker/docker-flask repo. You should use the
python:3-onbuild base image. You won’t need to add any more commands to the Dockerfile - just complete the three stubbed out already.
You may also find the Docker User Guide’s section on “Building an image from a Dockerfile” to be useful: https://docs.docker.com/userguide/dockerimages/#building-an-image-from-a-dockerfile
When you’re done, you can try building your Docker image with the docker build command:
docker build -t flask-app .
Be sure to pass that
-t option to your
docker build command. This tells Docker what to name the image created at the end of the build process.
When Docker can successfully build your Dockerfile, test it by starting a new container from your new image using the
docker run command. Don’t forget to include the port forwarding options you learned about in the last exercise.
If you did everything right, you should be able to see
Hello! I am a Flask application when you visit your container in your web browser.
If you get stuck, you can reference the
solution branch of the
docker-flask repository on GitHub: https://github.com/atbaker/docker-flask/tree/solution
Pushing to the Docker Hub¶
The Docker Hub is sort of like the GitHub of Docker images. It’s the main place people store their Docker images in the cloud.
Before we can take our Dockerized Flask app to another computer, we need to push it up to the Docker Hub so that we (or other people) can pull it down on other machines.
First, create an account on the Docker Hub if you haven’t already - it’s free: https://hub.docker.com/account/signup/
Then, login to that account by running the
docker login command on your laptop.
We’re almost ready to push our Flask image up to the Docker Hub. We just need to rename it to our namespace first.
docker tag command, tag the image you created in the previous section to your namespace. For example, I would run:
docker tag flask-app atbaker/flask-app
flask-app is the tag I used in my
docker build commands in the previous section, and
atbaker/flask-app is the full name of the new Docker image I want to push to the Hub.
All that’s left to do is push up your image:
docker push atbaker/flask-app
Go to your profile page on the Docker Hub and you should see your new repository listed: https://registry.hub.docker.com/repos/
Congrats! You just made your first Docker image and shared it with the world!
In the next section, you will learn how to use Docker to run a more complex web application. When you’re ready, move on to Exercise 3: Full stack Docker!