Packaging Clojure Applications

Overview
Principal Developer Rhodri Pugh explains the process we've put in place at Box UK to effectively and stably package Clojure applications.
Author
Rhodri Pugh
Date

Rolling out Clojure

At Box UK we try, where practical, to be technology agnostic and pick the best tool for the job. Over the next few years I see Clojure (and possibly other JVM languages like Scala) becoming more and more important in solving the problems that both we and our clients encounter.

Internally I’ve been trialling small Clojure applications and libraries for some time, but if we’re going to be rolling these out to production environments then we’re going to need a stable way to do it.

Build Problems

In our current deployment process, using RPMs for all our applications has become standard. But doing some casual Googling on how to get started building these for Clojure projects turned up very few results…There’s a plugin for Leiningen, but we use a slightly more custom process with Mock to create a clean chroot’d build environment, and I couldn’t see how this was going to work for us.

Another problem (before even being able to consider the previous plugin) is Leiningen itself. This is the de facto standard tool for managing Clojure projects, but unfortunately the packaged version is way out of date. This causes problems as our build servers need to be managed in the same way as all our other boxes: packaged software only please.

None of this is too challenging though, so I’ll go over what we put in place to effectively package Clojure applications.

Leiningen

The first step is packaging Leiningen. With the most recent version I could find being 1.7-something, we needed to roll our own, which we’ve packaged under the name boxuk-leiningen to avoid naming conflicts should an official package appear. Here’s the interesting bit:

We’re pulling down a specific version to install globally, and tweaking the shell script to reference it:

If someone tries to self-install they’ll probably get some unexpected behaviour…but at the moment we’re mainly just pulling this in for our RPM builds so it doesn’t matter too much.

Applications

With Leiningen now available the second part is packaging individual applications. The setup we’ve started rolling with is far from perfect, but it’s a work in progress and something we will improve. The project is available on Github, so go check it out if you’re interested. Again, while it’s tailored slightly to our specific process, it should be a good starting point if this is your first attempt at doing this kind of thing.

First the spec file:

As you can see, we pull in our custom Leiningen RPM as a build dependency. Rather than embedding web applications within a container like Tomcat we’re using the lein-bin plugin to create standalone ‘binaries’ for each application. This then packages all the dependencies and just requires Java on the servers being deployed to. It also lets the application decide which kind of web server it uses (if any of course).

The rest of the file is standard RPM stuff; setting the application up using chkconfig with an init script to manage it:

This then allows us to easily install and manage the application with the usual service start/stop/restart  commands.

Conclusion

It’s a pretty simple thing, but this solution allows us to start rolling out internal Clojure apps and pilot projects where it makes sense.

The code is on Github:

https://github.com/boxuk/leiningen-rpm

https://github.com/boxuk/clojure-rpm-template

And hopefully if you’re looking to do the same then this will be a helpful starting point – let me know in the comments.

Add your comment

If provided, we will link to this from your name