There are many ways to deploy a Phoenix web application in a Virtual Private Server (VPS). One of them is through Dokku.

In this post, I will show you how you can use Dokku to deploy Phoenix applications using Azure as VPS and why you should consider this cheaper approach.

Credits to Ashley Connor who shared his wisdom in his post entitled Deploying a Phoenix Application to Dokku where I drew inspiration from in writing this. Thank you!

Why Dokku?

Dokku is a docker-powered PaaS that can use Heroku's buildpacks. If you're new to Phoenix, you may find that deploying in Heroku is the easiest way to go. Thanks to HashNuke and Gjaldon for creating these buildpacks.

At the time of this writing, Exrm has been recently replaced by Distillery. With this big change, there's yet to be a clear pattern on how to use Distillery with E-Deliver more effectively although there are blogs about certain attempts. The official page of Phoenix is still promoting Exrm to which my doubts prevent me from agreeing to completely.

So for now, I'm betting on those Heroku buildpacks.

The only limitation of Dokku is that it's built for a single instance of VPS. It's not for high availability & fault-tolerant production application where you need a web cluster under a load balancer. You may want to try Flynn for that.

It's best for applications that are cost-conscious.

Why Azure?

Azure is ideal for applications that require single-instance with cheaper rates. Thanks to their free credits, you can get started without paying.

Free Credits!

Microsoft is generous in providing free credits. If you're new to Azure, grab their $200 free credit upon registration and build your own VPS.

Other than that, Azure also offers a healthy ecosystem. You can easily spin-up a Postgresql Database server instance with replication.

Setting up Dokku in Azure

There are two ways to do this:

  1. Easy way
  2. Not so hard but cheaper way

If you choose the easy way, you'll be redirected to a post that uses the Dokku deployment in Azure. It's super easy to do, but in terms of VMSize selection, you won't be able to choose the cheaper A-Series (starts at $14/month) of VMs.

So, allow me to share with you the not so hard approach.

Create VM

  1. Once inside the dashboard, select Virtual Machines then click Add
  2. Select Ubuntu Server 16.10, then click Create with Resource Manager
  3. Enter the basic details, select VM disk type HDD, then click OK
  4. Click View all, then choose A0 size
  5. In the settings, you need to edit the Network Security Group to add HTTP & HTTPS inbound rules
  6. Review the summary then click Ok
  7. Once creation of VM is complete, connect to it through SSH

Install Dokku in VM

  1. Follow this guide when installing Dokku
  2. In case you get an error about docker-engine, install docker-engine in your VM first then rerun step 1.

Upload Custom SSH for Dokku (optional)

This may not be always required, but in case you get an Access Rights error when you do git push dokku later, then this is the fix:

  1. Create a custom RSA key: ssh-keygen -t rsa
  2. Enter custom as the file name
  3. Just set an empty passphrase
  4. Add the custom.pub key to Dokku's VM by running this command: (refer to the settings of the VM)
cat ~/.ssh/custom.pub | ssh <username>@<servername>.<location>.cloudapp.azure.com "sudo sshcommand acl-add dokku custom-identifier"

Add an application in Dokku

You'll know that the installation is good when you can use the dokku command in SSH. For now, we'll name our application phoenix_chat

  1. SSH to your VM
  2. Create an application in Dokku
$ dokku apps:create phoenix_chat
Creating phoenix_chat... done

Clone Phoenix application

To shortcut our way, you can simply clone a sample application I forked from Chris McCord's Chat App which I've already updated to Elixir version 1.2.

git clone https://github.com/ngdelcastillo/phoenix_chat_example.git

Build the project and test if it's working in your local machine. If it's all good, add a new git remote pointing to your Dokku VM.

git remote add dokku dokku@<domain>:phoenix_chat

For the domain, use the public domain assigned by Azure in your VM.

Set the environment variables

The great thing about Dokku is that it follows the same style as the Heroku env variables.

Generate a secret key: mix phoenix.gen.secret

dokku config:set phoenix_chat SECRET_KEY_BASE=<secret_key> HOSTNAME=<domain>

Setting up database (optional)

The cloned app doesn't have a database. But in case your app has one, this is how you can setup PostgreSQL:

SSH to your VM then install Dokku Postgres pluggin

dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres

Then create the database for itself

dokku postgres:create phoenix_chat_prod

Link the database to the container of the application

dokku postgres:link phoenix_chat_prod phoenix_chat

The format is: postgres:link <db_name> <app_name>.

For prod environment, I would advise you to create the database in a separate VM outside of Dokku.

Deploy the application

Now on your local machine, you can easily deploy your application by:

$ git push dokku
-----> Cleaning up...
-----> Building phoenix_chat from herokuish...
-----> Adding BUILD_ENV to build environment...
-----> Multipack app detected
...

If it's all good, you'll be able to see the link to the application in your VM. Access that to check if the site is working.

Assigning a Domain

The great thing about Dokku is that you can host multiple applications in a single VM using its VHOST feature. Dokku will assign a port for each application.

But in case your intention is to host a single application that you want to assign a custom domain, then the command will be:

$ dokku domains:add phoenix_chat <custom domain>

This will configure NGINX to listen to port 80 and set the server to the <custom domain>. You just need to configure the A record or CNAME of your DNS to point to the IP or link the Azure VM provided.

That's it. Drop your comments below if you have any.