kaashif's blog

Programming, with some mathematics on the side

OpenShift vs Heroku: Haskell

2015-03-30

There are a few Platform as a Service (PaaS) services out there, and the most famous is probably Heroku. I know I've had people come up to me and suggest using Heroku for the next big thing they're planning. There is a problem with Heroku: it's not free (libre). That didn't stop me from at least trying it out to see what all the fuss was about.

Deploying a Haskell app on Heroku

Obviously, it wasn't as easy as just git push heroku master, or this post wouldn't exist. No, it was more complicated than that.

I couldn't just push my Happstack app (a toy app, now hosted at http://quenya.kaashif.co.uk) to Heroku, so I had to do a bit of searching around. The best way to do this was to create an app with the buildpack set to either https://github.com/begriffs/heroku-buildpack-ghc or https://github.com/mietek/haskell-on-heroku. The latter was apparently faster, so I tried that out.

Setting the buildpack was as easy as:

$ heroku buildpack:set https://github.com/mietek/haskell-on-heroku.git -a quenya

Apparently, it was now just as easy as pushing. So I tried:

$ git push heroku master

And it failed, with the following errors:

*** ERROR: Cannot build sandbox directory
*** ERROR: Failed to deploy app
*** ERROR: Deploying buildpack only

There was some other output, too, but those were the important lines. This wasn't supposed to happen. After looking around on the tutorial page, I see that this error occurs when you're trying to build using a one-off dyno. Maybe I could still make it work!

$ heroku run -s 1X build

And that failed, telling me private storage was expected (an S3 bucket). Well, I should've expected that, I suppose, considering the errors I got when the push failed are only supposed to occur when trying to use private storage.

Well anyway, let's try the other buildpack.

Trying the other buildpack

I set the buildpack to the first one I looked at:

$ heroku buildpack:set https://github.com/begriffs/heroku-buildpack-ghc -a quenya

That worked fine. Then, I pushed.

$ git push heroku master

It seemed to be going well, GHC was downloaded, cabal-install was downloaded, and it was about to run when suddenly:

cabal: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory

And it was going so well! If I got this error on my machine, I'd just do some dirty symlink trick to make cabal think it had the right library, but I couldn't do that on Heroku, since I didn't have permission to do anything.

Now that I think about it, this means that the haskell-on-heroku buildpack would have probably failed too, even if I set up an S3 bucket for it.

Anyway, I'd had enough of Heroku and decided to try out OpenShift.

Getting started with OpenShift

I visited https://openshift.redhat.com and signed up for a free account. It was simple enough to make an application, I just had to select a "cartridge" (basically a set of preinstalled libraries and programs), add my SSH key, and pick a name.

There was already a Happstack cartridge which came with happstack-server, blaze-html, and all the libraries I needed, bar a few. Before pushing my app, I decided to install rhc, the command line tool for OpenShift, like heroku.

It has some cool features, like rhc port-forward, which sets up a tunnel so you can access the internal services (Redis, PostgreSQL etc) from your own computer, on localhost. For example, if you run rhc port-forward, you could access PostgreSQL on 127.0.0.1:5432. Cool, right? I suppose Heroku must have something similar, but this isn't supposed to be a balanced blog post.

Anyway, I sshed into the application server to check things out, and it looked like a normal RHEL server, without anything weird or virtual-looking (although it probably is virtual). I had a home directory in /var/lib/openshift/, alongside a number of others. cabal was actually installed, unlike on Heroku, so I didn't need any "buildpacks": the build would take place exactly as it would do on my computer.

All I had to do was git push <really long uri> and it worked. All that happened was that cabal run <host> <port> was run (or something to that effect), and it started the app. Simple, right?

Moving a static site to OpenShift

This is easy, although there isn't a "static site" cartridge. All you have to do it pick a PHP cartridge, and Apache just serves the root directory of the repository (with mod_php enabled). So I just generated my blog, pushed to a new PHP app, and Apache served my site. Easy.

Conclusions

OpenShift is good, use it instead of Heroku. I can't speak for the paid options, but it's a lot easier to deploy Haskell on OpenShift.

Note: I have almost no experience in using either, except for what I've written in this article.