The Hapistrano tool that we at Stack Builders use for deployment has been almost completely rewritten and new features have been added. The reason for such a rewrite was that we wished to make configuration easier and to avoid re-building our software on target hosts when possible, thus making CI cycles that deploy our software much quicker.

First, let’s mention the improvements that don’t add new functionality, but make using Hapistrano easier. One of those features is the real-time logging of all commands we send to the target host. Every time a command is executed we get information which machine is this, on which port we are running SSH and most importantly, the exact command that we run and what the output will be. The print-out looks like this:

*** stackbuilders@my-project-staging.stackbuilders.net:22 ********************** $ mkdir -pv /var/projects/my-project/repo/ *** stackbuilders@my-project-staging.stackbuilders.net:22 ********************** $ mkdir -pv /var/projects/my-project/ctokens/ *** stackbuilders@my-project-staging.stackbuilders.net:22 ********************** $ ls /var/projects/my-project/repo/refs/ heads tags *** stackbuilders@my-project-staging.stackbuilders.net:22 ********************** $ (cd /var/projects/my-project/repo/ && git fetch origin) From github.com:stackbuilders/my-project * branch HEAD -> FETCH_HEAD *** stackbuilders@my-project-staging.stackbuilders.net:22 ********************** $ git clone /var/projects/my-project/repo/ /var/projects/my-project/releases/20170225121307/ Cloning into '/var/projects/my-project/releases/20170225121307'... done.

Another improvement is that hap (this is the name of Hapistrano command line tool) now uses YAML files for configuration instead of reading a collection of environment variables. By default hap assumes that configuration file is called hap.yaml , but you can specify a different file using the -c command line option (or have several of them, e.g.: one for staging, another for production). The configuration file looks like this:

deploy_path : /var/projects/my-project host : my-user@my-server.com port : 2222 # now you can specify SSH port to use repo : git@github.com:my-user/my-repo.git revision : origin/master build_script : # now everything is in a single file - stack setup - stack build - export DBM_DATABASE="dbname=my_database" && export DBM_DATABASE_TYPE=postgresql && export DBM_MIGRATION_STORE=migrations && ~/.local/bin/moo upgrade restart_command : sudo systemctl restart my-app

Your deploy command may be as simple as:

$ hap deploy

It’s worth mentioning that playing locally with Hapistrano has never been easier. You can omit (or just comment out) the host parameter and localhost will be assumed. This way you can test your build script on your local machine without messing with a real server.

New features include:

The ability to specify an SSH port in case you need to use something other than the default — 22 (this is done by setting port parameter in the configuration file).

The automatic filtering of targets for rollback, so that only successfully deployed releases are selected. We consider a release successful if all its deploy commands executed with zero output codes and no errors happened during copying of files and other operations. You don’t need to do anything to enable this feature, it works by default. If you have previously used older Hapistrano, which was not keeping the record of successful deploys, the tool is able to detect that and to fallback to the optimistic mode like the older Hapistrano versions just selecting the previous deploy.

The ability to copy arbitrary files and directories from the local machine to a target server (use the copy_files and copy_dirs parameters). This allows you to build projects on e.g. a CI server and copy compiled binaries on target host.

The ability to concurrently deploy the same application to several machines. This is done via the targets parameter that you specify instead of host and port . Every item in targets list has a host and may have a port specified for it.

Here is an example the targets parameter:

targets: - host: myserver-a.com port: 2222 - host: myserver-b.com

Since executables built on a CI server are often suitable for running on the target host, the new copying feature helps us immensely: the duration of CI circle with deploy is now almost twice as short. Not to mention the fact that some servers were incapable to run GHC and compile bigger projects — they just ran out of RAM. Now this problem is history.