At this point, Docker needs little introduction. Running applications in a container is all the rage right now, and the Fedora Project has been working hard to make sure that it’s easy to use Fedora to run containers, and to run Fedora inside a container. To make it even easier, the project has a set of Dockerfiles that let you get started immediately with a containerized application to build on.

The project has Dockerfile that defines more than 20 applications – ranging from Ansible to WordPress. If you haven’t worked with Dockerfiles previously, let’s take a look at using Dockerfiles and how you can build an image from them, and run your application.

Getting Dockerfiles

The Fedora Dockerfiles are available as a package, or you can just grab them on on GitHub.

If you want to grab the package, look for the

fedora-dockerfiles

package (no shocker there, huh?). They’ll be installed under

/usr/share/fedora-dockerfiles

.

Generally, though, I recommend grabbing the Dockerfiles directly from GitHub. Those are likely to be more up-to-date, and you can just grab one file or go ahead and clone the entire repository and track any change you might make. And, of course, you could submit changes back to the project too. If you find errors, make interesting changes, or create new and interesting Dockerfiles please feel free to submit a pull request.

To clone the entire repo, do:

git clone git@github.com:fedora-cloud/Fedora-Dockerfiles.git

Naturally, you’ll need to have git installed. If you don’t, install the

git

package (e.g.

sudo dnf install git

).

Create an Image from a Dockerfile

Let’s say you have grabbed the Fedora-Dockerfiles repo from GitHub. Let’s take a look at the Nginx Dockerfile and then build it.

Reading the Dockerfile

The Dockerfile is actually quite short, just 11 lines:

FROM fedora MAINTAINER scollier <scollier@redhat.com> RUN yum -y update && yum clean all RUN yum -y install nginx && yum clean all RUN echo "daemon off;" >> /etc/nginx/nginx.conf RUN echo "nginx on Fedora" > /usr/share/nginx/html/index.html EXPOSE 80 CMD [ "/usr/sbin/nginx" ]

Some of that is probably going to look very familiar if you’ve been working with Fedora for a while. As you can see, several lines are just using

yum

to update the package cache and then install the

nginx

package, and then run

yum clean

. Note that you could do this (and the additional

echo

commands) interactively. However, it’s way more efficient to put it in a Dockerfile.

Why do we do the

yum clean

each time? It removes the cache and makes the image smaller. (You can compare by building an image without the

yum clean all

and see how much larger the image is.) Note that the steps you use in the build will show up if someone does a

docker history

on the image, and it’s even possible to use

docker run

to run an individual layer of an image.

The

EXPOSE

directive exposes port 80 of the container to the host. By default, the container wouldn’t be listening on port 80 when you run it if you didn’t include this directive. Note that you can still use the

-p

directive to expose a port at runtime, but this saves a bit of typing…

Finally, the

CMD

directive tells Docker to run this when the container is spun up.

To sum up: This Dockerfile will tell

docker build

to build a container from the fedora image, run

yum

to update the package cache and then install

nginx

, update the Nginx configuration and create a default landing page (index.html).

Note that it doesn’t specify the version of Fedora that should be used. If you want to specify, be sure to add the version like so:

FROM fedora:21

Now we’re ready to go ahead and fire up the container.

Images vs. Containers

It may seem like a very subtle distinction, but when you first build a Dockerfile you have an image. When you actually run the image, you have a container.

Why does this matter? The simple version: images are immutable, containers are the images plus changes that are layered on them after they’re run and (potentially) modified. Even when a container is at rest (stopped) it’s still a container, and it retains things like network ports and resource limits the next time it’s started.

Let’s Roll!

Make sure you’re in the

nginx

directory of the repo you checked out and we’ll go ahead and build the image, like so:

sudo docker build -t username/imagename .

This command will tell Docker to do the following:

Read the Dockerfile in current directory (the . at the end of the command).

Build the image using the instructions in the Dockerfile.

the image using the instructions in the Dockerfile. Tag ( -t ) the image with with the “username/imagename” you specify.

So here’s the command I use, and note that I’d usually use

jzb

instead of

zonker

, but the username must be at least four characters.

sudo docker build -t zonker/nginx .

This will pull down the Fedora base image, if it’s not already present, and then run the commands in the Dockerfile. When finished, you can start a container from the image.

Running the Container

Now we’re ready to start a container from the image. Let’s go ahead and fire up Nginx and point it at port 8080 on the localhost — in other words, requests coming to the host running Docker on port 8080 will redirect to the Nginx container (on port 80).

sudo docker run -d --name f21nginx -p 8080:80 zonker/nginx

Naturally the name of the image (zonker/nginx) will be different for you, so substitute whatever name/tag you chose there.

Now when you make a request on port 8080 (e.g. http://localhost:8080) it will redirect to the Nginx process running in the container on port 80. So you’ll see whatever content that Nginx is serving, in this case just the test page.

Submitting Fixes and New Dockerfiles

Have a fix or want to submit a new Dockerfile? Feel free to submit a Pull Request (PR) on GitHub.

We also welcome folks who want to test the Fedora Dockerfiles, especially as we’re ramping up towards Fedora 22. If you have questions or comments on Dockerfiles, feel free to ask on cloud@lists.fedoraproject.org.