Quick Containers with Fedora Dockerfiles

dockerAt 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.
  • 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.

Using Software

9 Comments

  1. Eric Gillingham

    Why run yum clean all after both yum commands? Shouldn’t you just run it once after the last yum usage?

    • Joe Brockmeier

      No, because the layer will still have the cache – each RUN command creates a new layer. Try it yourself and see how the image size differs.

  2. Tomas R

    Formatting squashed 2 dashes into one en dash in:

        sudo docker run -d –name f21nginx -p 8080:80 zonker/nginx
  3. When will official Fedora 22 file coming out?

  4. Craig

    It seems a bit pointless to do:

    RUN yum -y update && yum clean all
    RUN yum -y install nginx && yum clean all

    When you could just use:

    RUN yum -y update
    RUN yum -y install nginx
    RUN yum clean all

    Why pull a full copy of the repo metadata twice?

    • Craig

      Don’t answer that — it was a dumb question. I momentarily forgot that Docker makes a snapshot for each command.

  5. Andrew

    For those on CoreOS: be aware there’s presently a bug that causes build to fail with a checksum error:

    https://github.com/coreos/coreos-overlay/issues/1153

    Workarounds here:
    https://github.com/docker/docker/issues/10180

Comments are Closed

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions