Deploy Early and Often: Deploying Phoenix with Edeliver and Distillery (Part One)


We will be setting up a Phoenix production environment on Ubuntu 16.04 LTS and deploy a simple Phoenix application using Edeliver and Distillery. We’ll be setting up a Droplet on DigitalOcean.

We will be compiling and deploying on the same server.

What you’ll need:

  • An Elixir environment set up on your computer
  • Any domain or subdomain


When it comes to learning Phoenix, deploying your application to a VPS is probably the most challenging part. I had developed an application with Programming Phoenix as a guide, and I wanted to deploy the finished application to a server. To my chagrin, it was almost impossible to debug the various cryptic error messages that came up. I realised that leaving deployment till last was a bad idea — the application had accumulated enough complexity that I was at a loss as to how to fix it. With so much technical debt, it was impossible to gauge which part of the process had gone wrong. It would have been easy to pinpoint errors had I deployed the application regularly from the beginning.

Whenever you develop a Phoenix application for any real-world use, remember to deploy early and often. This will save you hours of head scratching and hair pulling.

While there are a number of popular articles about deploying Elixir releases with Edeliver and Distillery, I had to piece together several different guides along with the Edelivery documentation in order to deploy successfully. Hopefully, this will serve as a “golden path” guide that would serve the needs of most small Phoenix applications.

Our Phoenix Application

Let’s start by creating a new Phoenix project. (You can skip ahead if you’re familiar with the basics)

We’ll set up git:

Set up your database. Open config/dev.exs and config/test.exs and edit the database configuration, then run:

Next, run:

Visit localhost:4000 in your browser. You should see the default Phoenix homepage.

Now, add the dependencies edeliver and distillery to mix.exs.

Run mix deps.get to fetch the dependencies.

Our DigitalOcean VPS

Let’s set up our DigitalOcean VPS. (If you aren’t already using DO, you’ll get $10 in credit via this referral link.)

Click Create Droplet on your DigitalOcean dashboard, and select:

  • Ubuntu 16.04.2 x64
  • 1GB/1CPU ($10/mo)
  • Any datacenter region
  • Under “Select additional options”: none are necessary
  • Your SSH key

Enter any hostname (for this guide, we’ll use deployphoenix), then click Create. Copy the ipv4 address, e.g. (replace with your own).

SSH into the server:

Let’s create a deploy user that we will subsequently log in with. You’ll be prompted for a password and other details for the user.

Next, we’ll add the deploy user to the sudo group.

Now, we’ll copy the SSH keys over to the deployuser’s home directory.

Let’s try SSH’ing in using a new shell window.

Locking down the root account

Let’s perform some basic server hardening, starting with preventing SSH access to the root account.

Edit the sshd_config file with sudo vim /etc/ssh/sshd_config (or use sudo nano). Change the line

PermitRootLogin yes


and save the file. Then, run:

sudo service sshd restart

Running updates

We’ll now update system packages before we proceed.

Setting up a firewall

Next, we’ll set up UFW.

Installing PostgreSQL

Let’s install PostgreSQL.

You may see an error like the following:

Let’s add the Postgres Apt repository. (I found this solution on the AskUbuntu site)

Now that we’ve installed PostgreSQL, let’s create a database.

This opens a psql console.

We’ve just created a database that we’ll later configure Phoenix to use. Type in \q to quit the psql console, then exit to return to the deploy user shell.

Installing NodeJS

Since we’re using vanilla Phoenix for this guide, that means we’re using Brunch for asset compilation. Brunch requires npm, and npm requires Node.js. Let’s install that now.

First, to add the Node.js PPA maintained by NodeSource, we use curl to retrieve the installation script.

Then, we run the script:

The PPA will have been added, and the local package cache will be updated as well. Now, we can install Node.js.

This installs npm as well. We will also need the build-essential package:

Let’s step back for a moment and review what we’ve got so far:

  • A bare-bones Phoenix application
  • An Ubuntu server ready for compiling and deploying

Next Up

Give yourself a pat on the back if you’ve followed along so far. In Part 2, we will continue our deployment process. We will build and deploy a release, then get it to play nice with nginx.

Part 2 is now up!

Web Application Development for innovative companies.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store