Continuous Delivery for Elixir (Part 1 — Introduction)

Jeff Weiss
May 27, 2016 · 3 min read

Who this is for

You are an Elixir developer (or aspiring to be). You have an application that you need to deploy to production and need to work with a formal Ops or DevOps group to get it there. Your application is not a good fit for Heroku or the like. Or you have an Elixir application already in production, but you feel there must be a better way than installing Erlang, Elixir, cloning the source and running mix. If you want to deploy a web application, you are interested in deploying behind nginx so it can handle SSL termination for you. I do not expect you to have an existing Continuous Delivery pipeline. I do not expect you to have ever built a system package before. I do not expect you to have a management solution like Puppet in place.


With this series I don’t expect to introduce cutting edge technology. I will not demonstrate how to deploy in Docker containers or in situations in which you should reach for Nerves or Zerg. I strive to cover the pragmatic middle of the pack. As so all the choices for tools in this Continuous Delivery pipeline are informed by “What is a widely available and tested technology that can solve this problem?” Another’s experience may have led to different tools in that market. These are mine, feel free to disagree with them.

I may turn this into a proper book at some point in the future. ¯\_(ツ)_/¯

Target Environment

Throughout this series we’re going to target deploying our Elixir project to a Debian 8 (Jessie) Linux virtual machine. Not because I have any particular affinity for Debian; in fact, quite the opposite — I want to spend as little time interacting with the Debian-ness of the virtual machine as possible.


If you’re an experiential learner who likes battlescars, this section may be enough for you. I intend it to serve as a high-level view of our continuous delivery pipeline and guide the topics as we delve further in later sections.

In Elixir parlance, the pipeline looks like this:

|> conform
|> jenkins
|> exrm
|> fpm
|> freight
|> puppet

For extracting existing project configuration elements, like database host or port number, into an external artifact, we’ll use conform.

For running our tests and subsequently building our release, packaging it, and sending it off to a package repository, we’ll use Jenkins to run exrm, fpm, and freight. I have a preference for dependency-free system packages because

  1. installing and configuring system packages is a well-understood and supported problem
  2. dependency-free packages lessen the amount of things that can go awry if handing off responsibility to other teams

To install our application on our target machine and configured it for that environment, we’ll use puppet and, for sensitive configuration parameters like password, hiera-eyaml.

Of this toolchain, Jenkins, freight, and puppet may have non-trivial setup costs. In my case, that cost had already been paid by my SysOps team. I will attempt to cover only as much as needed of setting up these tools in later sections.

What’s next?

In the next section, I plan to discuss the project that we’ll use as our test case.

Jeff Weiss

Written by

A man of infinite resource and sagacity. Filled with ‘satiable curiosity. A howler himself. All places are alike to me. 18A8 5300 B15A 36D1