Rewriting to Haskell–Deployment

Posted on March 14, 2020 by Riccardo

This is part of a series:

Deploy with Hapistrano

Stream was born as a Rails application. For that reason, we have been using Capistrano to deploy it. That’s why for the Servant code we have decided to employ Hapistrano:

Hapistrano makes it easy to reliably deploy Haskell applications to a server.

Following popular libraries like Ruby’s < Capistrano>, Hapistrano does the work of building the application with dependencies into a distinct folder, and then atomically moves a symlink to the latest complete build.

This allows for atomic switchovers to new application code after the build is complete. Rollback is even simpler, since Hapistrano can just point the current symlink to the previous release.

This is how we are currently using Hapistrano to deploy the code:

What follows is our hap.yaml:


First of all, we need to have Stack installed. This is needed because, with the above configuration, Hapistrano will build the app on the server on each deploy.

Secondly, we decided that, for the time being, we will be serving the Servant code under /servant. Also, our Servant app will be running on port 8080. So let’s have Nginx do the right thing:

Thirdly, we want Systemd to manage the Servant process. What follows is the unit configuration we are using:

Notice that haskell-exe lives inside the current release (i.e. latest) because we configure Hapistrano to stack install --local-bin-path . .

Lastly, we need to allow the stream user to restart the application by adding them to /etc/sudoers:

We automated all of the steps with Ansible.

We invoke it with:

And here’s the role: