From Fedora Project Wiki

Docker POC

This is a page to track a proof of concept of using Docker to run a simple Fedora infrastructure application. The application in question is a pastebin. The application runs on RHEL6, so there is a RHEL6 container running on a CentOS 7 host.

The infrastructure container

The first thing that you need to do is to build a container that has everything that you need to operate in Fedora infrastructure. Currently, this only includes dnf|yum repo configuration for Fedora Infrastructure. In the future, this could include more if we want certain things to happen on every container. The rhel6 container that is referenced below is the reference rhel6 container as shipped by Red Hat.

Dockerfile for the infrastructure container

FROM rhel6
ADD epel6.repo infrastructure.repo rhel6.repo infrastructure-testing.repo /etc/yum.repos.d/

Containerize the app

The next thing is to figure out what the app needs. This starts with the Ansible "role" for the application. Since the pastebin application is very self-contained, this makes it an ideal candidate. Also, this is an application which requires RHEL 6 to run, but we have a RHEL 7 host. Therefore, we start with the infrastructure container for RHEL 6:

FROM docker-fedora-infra-6

Then we go on to define what the application needs. First, it needs the RPM installation of the application, obviously. We can do this by running a command in the container build:

RUN yum -y install sticky-notes

This will run, inside the container that is being built, a yum installation of the package that I need, and all of it's dependencies.

Next, we have a custom skin and some configuration for the application. This is currently deployed via Ansible via static file deployments, below is the section of the Dockerfile that does this:

ADD skins/fedora/ /usr/share/sticky-notes/skins/fedora/
ADD sticky-notes.conf /etc/httpd/conf.d/
ADD sticky-notes.ini /etc/php.d/
ADD class_urlshort.php /usr/share/sticky-notes/classes/
ADD config.php /etc/sticky-notes/

This will copy files from the "build context" - think of it as the directory that the container is being built in - into the container. The last of these is somewhat special, and I had to cheat in order to make it work.

By "cheat", I mean that in Ansible this is a template that references the database credentials for the application. I had to statically hardcode that in the file, look at the next section for some thoughts on that.

Next, we need to tell the container how to start. This is accomplished as follows:

ADD run-httpd.sh /
RUN chmod 755 /run-httpd.sh
EXPOSE 80
CMD /run-httpd.sh

This will add a simple shell script to the root directory of the container and make it executable. The next command tells Docker that I want to "publish" port 80 on this container. It says nothing about the runtime of the container (multiple containers could want to expose port 80, since they run in separate network namespaces this isn't a problem - the runtime mapping isn't specified here). It's very important that the thing in CMD not exit before the application is finished executing, or the container will be destroyed.

To run this container, on the command line you would run

docker run -d -p 80:80 --rm paste-test

Some additional thoughts

  • Where and how do we host a docker registry (Atomic Enterprise Platform gives us a protected private registry - which we may want because....)
  • How do we store credentials in the container (or retrieve them externally to the container (Custodia?))?
  • How do we ensure that the container is updated?
  • How do we discover services (etcd?)?
  • Inventory (goes to the previous point...)
  • Failure detection/recovery (Kubernetes? Apache Mesos/Marathon?)
  • OpenShift?

Where is it?

Currently (2015-08-14) a transient cloud instance has a poc running (209.132.184.206). Currently only sysadmin-main has access, if you'd like to help and need access ping jds2001.