In this quick guide, we'll build a new Phoenix app, set up Heroku and deploy! 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
- Push everything to Heroku to deploy!
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
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)
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>"
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!
git add . git commit -m "prepares for heroku" git push heroku master
Originally published at Alchemist Camp