In this episode we build a new Phoenix app, set up Heroku and deploy our app. Heroku may not be the ideal choice for an Elixir app but Elixir and Phoenix is an ideal stack to run on Heroku!

If you haven't already installed and set up Elixir on your computer, go through the setup part of lesson 1 and then you'll be ready to follow along here. These are the steps we'll go over:

Sign up for Heroku (here)

Install the Heroku Toolbelt (download here)

Create a new Phoenix app

Create a new app for it on Heroku

Add the Phoenix static buildpack

Create a free tier database on Heroku

Change some settings in our project

Make a Procfile and elixir_buildpack.config for Heroku

and for Heroku Push everything to Heroku to deploy!

Quick start

We'll call our app Hello , so here's what we need to run:

mix phx.new hello cd hello git init heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git" heroku buildpacks:add https://github.com/gjaldon/heroku-buildpack-phoenix-static.git heroku addons:create heroku-postgresql:hobby-dev

Application files to change

Heroku stores secrets in system environment variables instead of a secrets file, so we can delete prod.secrets.exs . Then, we can update prod.exs to get the secrets we need from System.get_env . While we're there we can also set the app to use SSL and update the host name to whatever Heroku named our app when we created it. Finally add the database settings to the bottom of the file:

use Mix.Config config :hello, HelloWeb.Endpoint, load_from_system_env: true, url: [scheme: "https", host: "NAME_OF_HEROKU_APP.herokuapp.com", port: 443], force_ssl: [rewrite_on: [:x_forwarded_proto]], cache_static_manifest: "priv/static/cache_manifest.json", secret_key_base: Map.fetch!(System.get_env(), "SECRET_KEY_BASE") # Do not print debug messages in production config :logger, level: :info # Configure your database config :hello, Hello.Repo, adapter: Ecto.Adapters.Postgres, pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"), ssl: true, url: System.get_env("DATABASE_URL")

If your app is going to use channels, then update your user_socket.ex file to add a timeout for sockets. Heroku limits them to 55 seconds, so set the time out to something like 45 seconds to be safe:

transport(:websocket, Phoenix.Transports.WebSocket, timeout: 45_000)

Application settings for Heroku

By default Phoenix uses a pool size of 10. This is very low and ideally we want to use nearly as much as is available. On Heroku we have a maximum pool of 20, so we'll set our application to use 18 and just use 2 for mix tasks. We'll also generate a secret key with Phoenix and set that in Heroku so that the app can get it from the system environment in production:

heroku config:set POOL_SIZE=18 heroku run "POOL_SIZE=2 mix hello.task" mix phx.gen.secret heroku config:set SECRET_KEY_BASE="<SECRET PHOENIX JUST GENERATED ABOVE>"

New files to add

In the root directory of our app, we'll add two more files for Heroku—one called Procfile that has just one line:

web: MIX_ENV=prod mix phx.server

and one called elixir_buildpack.config that holds some configuration settings:

erlang_version=20.1 elixir_version=1.7.2 always_rebuild=false runtime_path=/app

Important: Make sure that both files have LF line endings. Heroku throws errors on CRLF!

Deploy!