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

Following popular libraries like Ruby's <http://capistranorb.com/
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.

Maintainer's Corner

Readme for hapistrano-0.3.9.2

Hapistrano

Hapistrano is a deployment library for Haskell applications similar to
Ruby's Capistrano.

Purpose

We created Hapistrano because:

Deploys should be simple, but as close to atomic as possible (eg,
they shouldn't require much application downtime).

Rollback should be trivial to achieve to bring the application back
to the last-deployed state.

Deploys shouldn't fail because of dependency problems.

How it Works

Hapistrano (like Capistrano for Ruby) deploys applications to a new
directory marked with a timestamp on the remote host. It creates this
new directory quickly by placing a git repository for caching purposes
on the remote server.

When the build process completes, it switches a symlink to the current
release directory, and optionally restarts the web server.

By default, Hapistrano keeps the last five releases on the target host
filesystem and deletes previous releases to avoid filling up the disk.

Usage

Hapistrano 0.3.0.0 looks for a configuration file called hap.yaml that
typically looks like this:

revision — the SHA1 or branch to deploy. If a branch, you will need to
specify it as origin/branch_name due to the way that the cache repo is
configured.

The following parameters are optional:

host — the target host, if missing, localhost will be assumed (which
is useful for testing and playing with hap locally).

port — SSH port number to use. If missing, 22 will be used.

shell — Shell to use. Currently supported: zsh ans bash. If missing, Bash will be used.

build_script — instructions how to build the application in the form of
shell commands.

restart_command — if you need to restart a remote web server after a
successful rollback, specify the command that you use in this variable. It
will be run after both deploy and rollback.

vc_action - Controls if version control related activity should
take place. It defaults to true. When you don't want activity like
cloning, fetching etc. to take place, set this to false.

linux - Specify, whether or not, the target system where Hapistrano will
deploy to is a GNU/Linux or other UNIX (g.e. BSD, Mac). This is set to true
by default so unless the target system is not GNU/Linux, this should not be
necessary. The platform where Hapistrano is running won't affect the
available options for commands (g.e. A Mac deploying to a Ubuntu machine,
doesn't need this flag)

release_format - The release timestamp format, the
'--release-format' argument passed via the CLI takes precedence over this
value. If neither CLI or configuration file value is specified, it defaults
to 'short'

keep_releases - The number of releases to keep, the
'--keep-releases' argument passed via the CLI takes precedence over this
value. If neither CLI or configuration file value is specified, it defaults
to '5'

linked_files:- Listed files that will be symlinked from the {deploy_path}/shared folder
into each release directory during deployment. Can be used for configuration files
that need to be persisted (e.g. dotenv files). NOTE: The directory structure must
be similar in your release directories in case you need to link a file inside a
nested directory (e.g. shared/foo/file.txt).

linked_dirs:- Listed directories that will be symlinked from the {deploy_path}/shared folder
into each release directory during deployment. Can be used for data directories
that need to be persisted (e.g. upload directories). NOTE: Do not add a slash /
at the end of the directory (e.g. foo/) because we use parseRelFile to create
the symlink.

run_locally:- Instructions to run locally on your machine in the
form of shell commands. Example:

run_locally:
- pwd
- bash deploy.sh

Note how we are even able to execute a bash script named deploy.sh
above. Be sure to use set -e in your bash script to avoid
headaches. Hapistrano will stop the execution on non zero exit
codes. Without the usage of set -e, there is a possiblity that your
bash script may return a zero exit code even if your intermediate
command resulted in an error.

After creating a configuration file as above, deploying is as simple as:

Environment Variables

Configuration files are parsed using
loadYamlSettings,
therefore, variable substitution is supported. Considering the following configuration file:

revision: "_env:HAPISTRANO_REVISION:origin/master
...

The revision value could be overwritten as follows:

HAPISTRANO_REVISION=origin/feature_branch hap deploy

What to do when compiling on server is not viable

Sometimes the target machine (server) is not capable of compiling your
application because e.g. it has not enough memory and GHC exhausts it all.
You can copy pre-compiled files from local machine or CI server using
copy_files and copy_dirs parameters:

src maybe absolute or relative, it's path to file or directory on local
machine, dest may only be relative (it's expanded relatively to cloned
repo) and specifies where to put the files/directories on target machine.
Directories and files with clashing names will be overwritten. Directories
are copied recursively.

Deploying to multiple machines concurrently

Beginning with Hapistrano 0.3.1.0 it's possible to deploy to several
machines concurrently. The only things you need to do is to adjust your
configuration file and use targets parameter instead of host and port,
like this:

host item is required for every target, but port may be omitted and
then it defaults to 22.

The deployment will run concurrently and finish when interactions with all
targets have finished either successfully or not. If at least one
interaction was unsuccessful, the hap tool will exit with non-zero exit
code.

The log is printed in such a way that messages from several machines get
intermixed, but it's guaranteed that they won't overlap (printing itself
is sequential) and the headers will tell you exactly which machine was
executing which command.

If you don't specify host and targets, hap will assume localhost as
usually, which is mainly useful for testing.

Docker

If you would like to use Docker, there is a lightweight image
available on Docker Hub.