Last time we talked about "Building a fedora-based rocket container", so today we're going to use that as a base to build a container for running NodeJS applications.
If you are just joining us, please go back and read "Building a fedora-based rocket container" as the post includes instructions on how to get set up with
actool and introduces the basics of building a container.
Building a NodeJS rkt container
While it is possible to statically compile node, native npm modules will sometimes need to link off of libraries included in the system. So for this particular demonstration, we're going to use the Fedora container we created in the previous post as a base for our node container.
Back to acbuild
Our acbuild procedure is going to look something like this:
acbuild begin sudo acbuild dependency add <your domain>/fedora:latest sudo acbuild set-name <your domain>/nodejs sudo acbuild label add version "4.2.3"sudo acbuild run -- /bin/bash -c "curl https://nodejs.org/dist/v4.2.3/node-v4.2.3-linux-x64.tar.gz | tar xvz --strip-components=1 -C /usr/local"sudo acbuild write nodejs-4.2.3-linux-amd64.aci sudo acbuild end
Let's go through this step by step:
sudo acbuild dependency add <your domain>/fedora:latest
This tells acbuild to use the Fedora container we built in the previous post. As you can see, we're also specifying a version of
latest. acbuild will first check the local container cache to see if it exists, otherwise it will use http based discovery to location the container (more on discovery and how to set it up to come in a later post)
acbuild label add version "4.2.3"
Since we're pulling in node v4.3.2, we'll tag the version of our container as such.
sudo acbuild run -- /bin/bash -c "curl https://nodejs.org/dist/v4.2.3/node-v4.2.3-linux-x64.tar.gz | tar xvz --strip-components=1 -C /usr/local"
acbuild run is analogous to the RUN parameter you would find in a docker file; it can be used to execute a command within the container. In the case of acbuild (and rkt), what happens is acbuild actually starts systemd-nspawn to run the command against the rootfs as defined by the included dependencies.
sudo acbuild write nodejs-4.2.3-linux-amd64.aci
Now we're getting a little more fancy with our file naming. In this case, we have named our aci in a way that allows us to make it discoverable later on, following the format of:
So if I named my container
seanmcgary.com/nodejs, the discovery mechanism would at:
Packaging an application
Now that we have our nodejs base container, we can create another container to house our test application. A while back I wrote a little app called
stupid-server that can be found over on github at seanmcgary/stupid-server. Let's create our container:
# first clone the repogit clone https://github.com/seanmcgary/stupidServer.git acbuild begin sudo acbuild dependency add <your domain>/nodejs:4.2.3 sudo acbuild set-name <your domain>/stupid-server sudo acbuild label add version 1.0.0 sudo acbuild copy ./stupid-server /stupid-server sudo acbuild set-exec -- /bin/bash -c "node /stupid-server"sudo acbuild write stupidServer-1.0.0-linux-amd64.aci sudo acbuild end
We have some new commands in our process:
sudo acbuild copy ./stupid-server /stupid-server
This one is pretty straightforward - takes a local file/directory and a destination path of where to put it in your container.
sudo acbuild set-exec -- /bin/bash -c "node /stupid-server"
Here, we are specifying what to run when rkt executes our container.
set-exec is analagous to
CMD <command> found in a Dockerfile.
Running our application
As a quick recap, we have an application that inherits a chain of containers that looks like this:
fedora --> nodejs --> stupidServer
Now we can actually run our container with rkt:
sudo rkt run --insecure-options=all --net=host ./stupidServer-1.0.0-linux-amd64.aci rkt: using image from local store for image name coreos.com/rkt/stage1-coreos:0.13.0 rkt: using image from file /home/core/node/stupidServer-1.0.0-linux-amd64.aci rkt: using image from local store for image name seanmcgary.com/nodejs,version=latest rkt: using image from local store for image name seanmcgary.com/fedora,version=latest
If you want to push it to the background, you can also run it with systemd-run:
sudo systemd-run rkt run --insecure-options=all --net=host /home/core/stupidServer-1.0.0-linux-amd64.aci
Now with your container running, you should be able to hit your server:
curl http://localhost:8000/ 2015-12-16T00:36:46.694Z
That's it! Now that you know how to build containers based off of other containers, you should be able to figure out how to deploy your own app in a containerized fashion.
Next time, we'll talk about how to set up discovery so that you can host your containers in a central location.