Elixir Deployment Tools - General Discussion, Blog Posts, Wiki

General discussions and wiki for Elixir deployment tools - feel free to edit in any useful info.



The primary tool for building releases of Erlang applications. Can work with Elixir applications as well with some additional effort. Does not auto-generate appups for hot upgrades/downgrades. Natively supported in erlang.mk, rebar2, and rebar3.

Elixir Release Manager (exrm)

Now deprecated in favor of Distillery, this has been the predominant tool for building releases of Elixir applications. It is Mix-only, auto-generates hot upgrades/downgrades, and ultimately is an automation wrapper around Relx.


The latest iteration of release tooling for Elixir applications, it is written entirely in Elixir, and is tightly integrated with Mix, allowing it to further simplify the process of building releases. It is a replacement for exrm, and while similar, it’s ergonomics are significantly better, is more extensible, and is considerably faster than exrm.


Based on Deliver, Edeliver builds on Distillery/Exrm/Relx’s release generation and offers much more complete automation of the entire deployment process, from building releases, generating upgrades, deploying to one or more hosts, and more.


Similar to Edeliver. Supports Distillery.


Simple deployment and server automation for Elixir. Bootleg is a simple set of commands that attempt to simplify building and deploying elixir applications. The goal of the project is to provide an extensible framework that can support many different deploy scenarios with one common set of commands.

Blog Posts



What about using tools (that are popular in other languages) that we may already be familiar with, such as Capistrano or Mina? I’m interested in hearing what others are using…


I’m also interested in edeliver. Are there any more in-depth writeups about it somewhere? The Platafromatec one is quite scarce. I’m not 100% sure how I want to handle ENV variables.

In another project I worked on we did it like this:

  • Put production specific variables as ENV variables on our CI system (Travis)
  • If test fails, do nothing.
  • If test passes:
    • run mix release and so on with MIX_ENV=staging (staging.exs had mostly hard coded configs)
    • run mix release and so on with MIX_ENV=prod (prod.exs used System.get_env etc to get the ENV vars)
    • Upload both prod and staging releases to S3

When deploying we used capistrano and when running cap staging deploy it looked for a staging release built for the current commit, if it found one it uploaded it to the server and started it. If there were no release it had probably failed on our CI so the script printed an error message and bailed.

The nice thing about this was that the releases was built with the correct environment configs directly on our CI system (no need to worry about the ENV vars on the hosts). The downside would be that we didn’t deploy the EXACT same release on staging and prod.

Handling secrets is always an annoyance…

With edeliver you can link different configs (eg. sys.config) but then you need to install this on your servers somehow. Also, each developer needs the config if he/she needs to add a config and deploy it.

How do you manage that?


I enjoyed this talk at EmpEx about edeliver https://www.youtube.com/watch?v=H686MDn4Lo8


Seems like a great talk! Thanks!

1 Like

I added How We Deploy Elixir Apps which was linked from Elixir Radar.


Not strictly deployment per se, but exrm seems relevant here, but thus far not mentioned directly (I haven’t watched the linked talk yet).

I’m working on a ci pipeline for a new app now, and wanting a way to save and share what I’ve learned is what brought me to this thread. I’ll edit the lead post with a few of my findings, but wanted to share a bit of my process.

I have recently history with python and boto3 as well as aws, so thats the platform I’m targeting. My first pass has been fairly simple scripts using the python fabric tool. I’d like to make an elixir based process via mix tasks at some point, but haven’t had time to see what is already out there nor to write my own.

1 Like

Distillery vs. Exrm vs. Relx


Oh that looks fascinating, and it looks like it should fix the couple of annoyances that exrm had (thanks to relx). ‘edeliver’ has major issues for us here (since we use both windows and linux and its windows support was… well, crap…) so we’ve ignored it.


New blog post by Sam Corcos: Making Database Changes in a Deployed Phoenix App


A few links I came across:
Serving Phoenix and Continuous Deployment

How I Built My Own Heroku for Phoenix Apps: Part 1

The second link introduces a deplyment tool, called Gatling


Hi there, I’m new in the word of Erlang and Elixir. I was wondering how Elixir and Erlang deployments fits on Immutable Infrastructure pattern, I’ve been using lately Docker and Mesos/Marathon so I’m not used to modify servers with tools like Capistrano or Mina, I don’t know how tools mentioned where deal with infrastructure changes, it would be great to hear from your experience on this matter, thanks in the advance!.

Might need a specific example to say, but the most simple case is just a rolling restart, shutdown old code (and docker image), then spool up the new version. You can always do in-place upgrades if the filesystem can be updated in the image too.

So, it’s recommended to use Docker for Elixir/Erlang deployments? or is better to use OTP/Hot code swapping?

I use docker but I upgrade the image in-place via hot code swapping on my larger deployment since I do not want the downtime.

Where can I read more about it because I’m not sure to understand how OTP/Hot code swapping and Docker play together… , sorry totally newbie here :slight_smile:

You’d just have to push the new release into the image (docker exec or whatever it is called now), then run the upgrade script. :slight_smile:

1 Like

The post says Exrm is now deprecated in favor of Distillery, but Phoenix documentation still uses Exrm: http://www.phoenixframework.org/docs/advanced-deployment. Is the documentation out of date?

BTW, the seeming “go to” solution for deployment, Edeliver doesn’t look very friendly to me: the syntax of “.deliver/config” file with its callbacks like “pre_erlang_get_and_update_deps” and commands inside of them like “__sync_remote” looks a bit dated.

Gatling looks promising: config files are easier to read and reason about.

I believe the Phoenix team is busy preparing for the 1.3 release and will revamp the deployment docs along with updates in other sections. Exrm still does the job, though, so it’s not as if the docs is broken :slight_smile:

Well, it’s bash after all, so it does feel dated. But I guess it is better for people familiar with ops in Linux servers. Shell scripts are quite flexible and dependency-free.

Gatling uses Elixir for its configuration so it blends nicely with the rest of the project. It also does several things more out-of-the-box than Edeliver (for example configuring nginx reverse proxy and creating init.d file). I have the impression that Edeliver focuses on “flexibility while being easy enough” while Gatling goes for “simplicity while being flexible enough,” but I might be wrong :slight_smile:

Also, if I understand the documentation correctly (from the readme), currently there are some limitations such as it builds the release on the prod system, therefore requiring the server to have Elixir (Edeliver can use separate build host so that you don’t need the prod host(s) to have Elixir installed).

If it works for you, then great!