Deploying a Phoenix app to Heroku
Tags: elixir, phoenix, heroku, deployment
Published: 2019-05-11 12:56:44

---
title: Deploying a Phoenix app to Heroku
published: true
description: A quick-start guide to deploying an Elixir + Phoenix app to Heroku
tags: Elixir, Phoenix, Heroku, Deployment
canonical_url: https://alchemist.camp/episodes/deploy-phoenix-heroku
---

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!

{% youtube Wwlz5zGgtFA %}

If you haven't already installed and set up Elixir on your computer, go through the setup part of [lesson 1](https://alchemist.camp/episodes/guessing-game) and then you'll be ready to follow along here. These are the steps we'll go over:

- Sign up for Heroku ([here](https://signup.heroku.com/))
- Install the Heroku Toolbelt ([download here](https://toolbelt.heroku.com/))
- 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
- Push everything to Heroku to deploy!

## Quick start
We'll call our app `Hello`, so here's what we need to run:
```bash
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:

```elixir
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:

```bash
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!
```bash
git add .
git commit -m "prepares for heroku"
git push heroku master
```

*Originally published at [Alchemist Camp](https://alchemist.camp/episodes/deploy-phoenix-heroku)*