BinaryWebPark

Elixir Phoenix Applications: Deploy to Heroku

March 28, 2017

Elixir Phoenix Applications: Deploy to Heroku

Recently, I ended up deploying a small Phoenix application on Heroku. Coming from Rails, I ran into a few hiccups and this post is my attempt to document those.

Elixir basics

Step 1: Configure Your Database

If you want to deploy to Heroku, the first step is to configure your database URL. Log in to Heroku to take the DATABASEURL_ environment variable and add it to your prod.exs file.

In config/prod.exs:

config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: System.get_env("DATABASE_URL"),
  database: "my_app_prod",
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  ssl: true

Step 2: Generate and configure a secret key

Generate a secret key with this phoenix command:

mix phoenix.gen.secret

# /AGxvYJmiVUi/puVVdIaKP/3uT6M0VDvBXaud3cbiVkC/G8xX5AmlKkLWFHDz6FC

Set an ENV variable on your Heroku server to store the secret key. In the example below, I set an ENV variable called SECRETKEYBASE on my Heroku server.

config :my_app, MyApp.Endpoint,
  http: [port: {:system, "PORT"}],
  url: [scheme: "https", host: "my-production.herokuapp.com", port: 443],
  force_ssl: [rewrite_on: [:x_forwarded_proto]],
  secret_key_base: System.get_env("SECRET_KEY_BASE")

# Do not print debug messages in production
config :logger, level: :info

# Configure your database - moved from prod.secret.exs
config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: System.get_env("DATABASE_URL"),
  database: "my_app_prod",
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  ssl: true

Step 3: Set up your other ENV variables

Specify a POOL_SIZE of 10 or less if you’re running on the free Heroku plan.

In my particular use case, I needed to connect to the YouTube API with an API key provided by Google. When I wanted to be able to connect to the API locally, I created a .env file.

To make it work, I had to issue a source .env every time I opened a new terminal window and ran my Phoenix application locally.

export API_KEY=XXX

Step 4: Configure your buildpacks

You’ll need to configure an elixir buildpack.

# Erlang version
erlang_version=19.0

# Elixir version
elixir_version=1.3.2

# make vars available at build time
config_vars_to_export=(DATABASE_URL API_KEY MIX_ENV POOL_SIZE SECRET_KEY_BASE)

always_rebuild=true

To run iex -S mix on Heroku, set config_vars_to_export. Without this, you will get errors when you run iex -S mix on Heroku.

Summary

If you follow these steps in addition to the Phoenix documentation, you will be able to successfully deploy your phoenix application on Heroku.