Moving an RHSCL app to Docker on Atomic
As many of you have probably heard, Red Hat announced a new “Docker server” at Summit. The new server is called “Atomic” and details can be found at the project home page. As you all know, I tend to be interested in using Software Collections to ensure the portability of applications. So, putting my
foot^W money where my mouth is, I decided to download Atomic, run it as a VM, create a Docker image with a Software Collection, and copy a previous app there, unchanged. The pros and cons of running an application as a Docker container are debated heavily elsewhere, so we won’t discuss the “why” (unless you tell us we should in the comments 🙂 ), just the “how.”
For a little context, I wrote an article about an application that let’s you interact with Twitter via IRC using node.js and RHSCL. The application is fairly simple, but could not be run with just base RHEL, so it was a great example of a RHSCL application.
First, I, Valhalla forbid, read the directions at the Project Atomic “Getting Started” page. Per the docs, I downloaded the xz file (which, weirdly, does not include “atomic” anywhere in the filename), extracted the qcow2 file, made a VM, and added some extra storage with another raw file. In general, I didn’t have any trouble with following the Quick Start Guide except for a couple confusing steps (which I think were a mismatch between the version of virt-manager used for the doc and the one in RHEL 7). Basically, you have to pick the VM name at the beginning and F20 is not a choice. I just chose a Fedora that was available.
However, when I went to go actually “use” the VM, I found myself to be mildly confused. Is Atomic meant to be used like Vagrant, where I run the Docker commands outside the VM, or should I be running the commands inside the running VM? Upon consultation with Joe Brockmeier, one of the community folks for Project Atomic, I found out that you run the commands in the VM. And, per Joe, “Langdon, I think you might be overthinking it.” To which I say, “yeah, I have a talent.”
Ok, now that Atomic is installed, I need to go make a container. After a few fits and starts, mostly related to pathing issues while using the “RUN” command, I got a decent Dockerfile working. You “run” this file by using the “docker build” command. Later, you “make the app go” with the “docker run” command. I have excerpted it below:
FROM centos # Install scls and nodejs RUN yum update -y RUN yum install -y centos-release-SCL RUN yum update -y RUN yum install -y scl-utils nodejs010 # Clean up RUN yum clean all #FROM 1angdon/node-scl-centos # ^^^ this is a good place to break to make multiple app containers #add app ADD . /src RUN cd /src; scl enable nodejs010 "npm install" CMD cd /src; scl enable nodejs010 "node server.js"
To start, you may notice I used CentOS as the base image. (Currently, RHEL is not available as a base image.) I then proceed to make sure everything is current. Then I move on to adding a repository for the Software Collections available in CentOS:
RUN yum install -y centos-release-SCL
I then do another update and then install the nodejs (v0.10) scl. I also install scl-utils, which, honestly, I think is a dependency, but better safe than sorry. I then clean up yum to remove anything it downloaded to try to save on space, as I won’t be downloading anything else via yum.
The next line is just a comment to show that if I was doing this in a “real” environment, I would probably break the Dockerfile here and use the part above the break as a base nodejs image. I then proceed to add my source files, basically (more on this later) the exact same ones from the earlier article. I then use npm to add my node dependencies. Finally, I have a “CMD” operation which will actually start the server when using the “docker run” command.
If you notice, I used a “cd /src;” at the beginning of each of the scl-related operations. For some reason, I was not having good luck with a “RUN cd /src” actually persisting the directory change for the next RUN command. This may be by design, or something I am missing.
Finally, as I said above, I “basically” used the same files from the repo, however, I found some bugs in the original source :). First, I got the code working again on RHSCL, then I proceeded with the above.
In conclusion, making Docker on Atomic version of a simple node.js app is really pretty easy. Let me know how you make out.