Deploy a Phoenix Application on Heroku

Since I heard of Phoenix, the Elixir framework on The Changelog Podcast, I've spent some time getting familiar with the framework. However when time came to deploy the application onto Heroku there were a couple of things that weren't initially obvious to me, like how to run brunch to compile the assets or how to parse the DATABASE_URL environment variable.


First we have to change the currently used buildpack to the multi buildpack which makes it possible to run the Node.js besides the Elixir buildpack.

heroku config:add BUILDPACK_URL=

Then add the file .buildpacks with the contents below which will pull in the buildpacks and run their compile script. The buildpack listed last will hereby be used to run the application.

# .buildpacks

Compile the assets

Now that we have multiple buildpacks we need to tell the Node.js one to run the postinstall hook after all the dependencies are installed. Just add the scripts part to your package.json and you're all set for Heroku to run the brunch build command.

# package.json
  "dependencies": {
  "engines": {
    "node": "~ 0.12.1"
  "scripts": {
    "postinstall": "node_modules/.bin/brunch build"

Parse the environment variable

When deploying the application to Heroku, the configuration variables will be exposed to the application via environment variables. For the database that means there will be a single String from which the username, password, host, etc. will have to be extracted. You could theoretically do that by hand defining those variables individually, however what happens if your database provider has an issue and suddenly decides to change the value behind your environment variable? - in order to avoid that, just put the code below in your prod.secret.exs file to help you split the configuration variable for the database.

# config/prod.secret.exs
defmodule Heroku do
  def database_config(uri) do
    parsed_uri = URI.parse(uri)
    [username, password] = parsed_uri.userinfo
                           |> String.split(":")
    [_, database] = parsed_uri.path
                    |> String.split("/")

    [{:username, username},
     {:password, password},
     {:database, database},
     {:port, parsed_uri.port},
     {:adapter, Ecto.Adapters.Postgres}]

Then instead of defining the arguments for your app separately, call the database_config function and you're all set.

# config/prod.secret.exs
config :yourapplication, Yourapplication.Repo,
  |> System.get_env
  |> Heroku.database_config

Run the database migrations

heroku run mix ecto.migrate

Since I'm pretty new to Elixir and even newer to the Phoenix Framework, this tutorial might lack some best practices, in which case please let me know so this post can be updated to reflect them.

Published: 2015-06-07

Tagged: Heroku Elixir Phoenix