Clojure and Heroku

I wanted to learn a little more about heroku and having just rolled off a Clojure project I thought it would be a good opportunity to do some more Clojure Development in my free time.

The idea for the application was stolen off a friend of mine. It is a tower defence game, but unlike most tower defence games the focus is on using real map data sourced from Open Street Maps. I'll look at gameplay later on when I have a better idea what I'm doing.

Having worked on a couple of Clojure projects recently I stole the project setup from the one we developed for GovHack since that was also deployed to heroku. I had no problem getting the basics working, got midje running and the code doing what I wanted it to do. The next step was getting Compojure working, again not too much trouble here, all stuff I'd done before. Now it was time to look at hosting it.

Heroku was something that I had been aware of for quite some time but had never got around to learning about. I downloaded the command line tool and had a new app in no time. I configured my procfile the same way we did for GovHack:

  lein ring server $PORT

Then came my first push. It appeared to go well. I browsed to my app - error. Ok, time to check the logs:

  Web process failed to bind to $PORT within 60 seconds of launch

Hmm, that strange. I played around with a few things and hurray! Success! But being a newbie I still had no idea why this was happening. I made more changes to my code and this error would appear again from time to time then disappear again. Time to do some reading.

I read a few articles about it. The Heroku documentation for Clojure gives you instructions on how to build a jar with an embedded Jetty serverlet. "Pffft, lein ring server is so much simpler" I thought. I re-read the server logs. It begins fine, it starts getting dependencies, then suddenly failure. I couldn't put my finger on it.

About a week later I was hacking away on another Clojure app and the problem suddenly made sense. It gets the dependencies every time it runs my app. If this takes more than 60 seconds Heroku kills it! I did a bit more research, the slug compiler has 15 minutes to compile your app while it only allows 60 seconds to run. So the solution is to compile it to a jar with an embedded serverlet and just execute the jar (just like the Heroku documentation says).

When Heroku compiles Clojure code it uses

  lein uberjar

which will compile your code and any dependencies into a single jar. I looked for a way to get Heroku to run

  lein ring uberjar

instead. If I could do this it would mean that I don't need to specify a main method and all of the other overhead. However, I couldn't find a way to do this. If there is a way to do this, feel free to get in touch and let me know.

With that my app was running consistently without a problem. Feel free to check out the code on Github.

Keep and eye for my next post where I started to run the app through snap-ci.