by Glenn Jones, published on 28/09/16
This walkthrough will show you how to set up deployment for an Elixir based Phoenix app with dokku, on a 5$/month digitalocean droplet.
I am using Dokku 0.6.5, Elixir 1.3.3 and Phoenix 1.2.0. Do
mix phoenix.new -v to see the version of Phoenix you’re using. I highly recommend using kiex to manage your Elixir versions.
I am assuming for this walkthrough that:
So, lets get started!
Configuring your app consists of three parts: tweaking the project settings, setting the right buildpacks and creating a Procfile.
For tweaking the settings of your project, have a look at ashleyconnor.co, paragraph 2. Those are all the relevant settings that need to be adjusted.
Then, create a
.buildpacks file in the root of your project and enter:
Buildpacks allow you to sit back while your app gets deployed. As you can see, they are basically mimicked by dokku from heroku. They are great. If you want to enforce a certain Elixir version, you can do that by adding settings for the buildpack. If you insist on using Elixir 1.3.3 for example, add a
elixir_buildpack.config file to the root of your folder and add
For more information about those settings, visit their repo.
Then create a
Procfile in the root of your project. The procfile is executed to activate your app, once it’s ready. We will later set the environment variable
MIX_ENV=prod, so for now the
Procfile can simply contain:
web: mix phoenix.server
Credit where due: this part of the walkthrough effectively comes from rubyfleebie. Go have a look at his blog if you’re also busy with Ruby
Go ahead and create a new droplet. Use ‘One-click apps’ and select
Dokku 0.6.5 on 14.04. Select the 5$/month size, select a region, add your SSH key, think of a nice name for your droplet and click
create. Mine will be called “magicaltestapp”.
Once your droplet is done setting up, test if you can ssh into it. Use
ssh root@the_ip_of_the_droplet. If it doesn’t work, go back and fix your ssh keys.
So, when ssh’d into your droplet, first do:
cat /root/.ssh/authorized_keys | sshcommand acl-add dokku dokku
Whatever the outcome of that command, this will ensure you can deploy with dokku.
Secondly, we’re going to make a swapfile that will ensure you have more space available when compiling dependencies. This way, we prevent the
(Mix) Could not compile dependency idna, /root/.mix/rebar command failed. If you want to recompile this dependency, please run: mix deps.compile idna
error that one can solve with a bigger droplet OR a swapfile (see this issue).
Again: this comes from rubyfleebie, I am paraphrasing here for your convenience
Read the RubyFleebie blogpost if you care what exactly the following commands do. Otherwise, simply execute the following commands, one-for-one.
sudo fallocate -l 2048m /mnt/swap_file.swap sudo chmod 600 /mnt/swap_file.swap sudo mkswap /mnt/swap_file.swap sudo swapon /mnt/swap_file.swap
/etc/fstab with your favorite editor (I use vim, so
sudo vim /etc/fstab). And add the following entry below the existing entry:
/mnt/swap_file.swap none swap sw 0 0. Then your swap file should be set up.
Ssh into your server and execute:
dokku apps:create magical_test_app. It’s possible to have multiple apps running on your droplet, just realise that you can only expose one to an actual domainname (as far as I’ve been able to figure out, please let me know if you know how to bypass this). The others will all be your-domainname.com:port-nr.
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git. Wait for the plugin to be installed and then do
dokku:postgres create magical_test_app_db. This will create a database. Then link that database to your dokku app by running
dokku:postgres link magical_test_app_db magical_test_app. That will expose a
DATABASE_URL and enable your application to use the db.
Your remote will be in the format of:
dokku@the_ip_of_your_app:your_app_name. For me I set my remote with:
git remote add dokku-production email@example.com:magical_test_app. Then push to the remote.
This will trigger a first deployment that should not fail.
Phoenix apps need two more variables to be available:
MIX_ENV. My app initially runs without them but it’s best to add them nonetheless.
You can set those environment variables by ssh’ing into your droplet and executing
dokku config:set your_app_name HOSTNAME=some_value.
HOSTNAME is usually your domainname. If you are not linking this droplet to a domainname, use the ip of your droplet plus the portnumber. You can see the portnumber at the very end of the console output when you deployed. Otherwise, run
dokku proxy:ports name_of_your_app to see it. It’s the
host port that you’re after.
So for example, I run:
dokku config:set magical_test_app HOSTNAME=126.96.36.199:48813 dokku config:set magical_test_app MIX_ENV=prod
An often forgotten last job is to run your migrations. Ssh into your droplet and run
dokku run name_of_your_app some_task. To migrate, for example, do
dokku run magical_test_app mix ecto.migrate. If you want to interact directly within your project, run
dokku run magical_test_app iex -S mix.
After doing this, your app should be ready to go. Visit your domainname or ip:hostname to visit the app. For me that would be