Deploying Phoenix application to Heroku

iRonin IT Team - Experts in software development
devops, heroku, phoenix

We like Elixir & Phoenix, and we like Heroku. So one day we thought: why not combine them? In today’s post we talk about how to deploy a Phoenix app to Heroku.

Phoenix is framework for the Elixir language, used to build fast, scalable web applications. Because Elixir runs on the Erlang Virtual Machine, it’s able to fully use all CPU cores without sacrificing code readability, robustness and security. It proves its values in low-latency, distributed and fault-tolerant systems. How many times have you heard: “Your call cannot be made at the moment because we are upgrading our servers”? Never? That’s because Erlang was created by Ericsson for handling these needs, within the context of telecommunication systems.

Then, on the other side, you have Heroku: a powerful platform for hosting applications written in multiple languages; Ruby, Python, Node.js, and Go, among others. It makes deploying, scaling and hosting a breeze.

Unfortunately Heroku by default does not support apps written in Elixir out of the box at the moment of writing. Luckily there are many 3rd party buildpacks that are compatible with Heroku’s official ones and can be used as a replacement or addon. In this article we will show you how to deploy Phoenix application using those extra buildpacks.

We assume you already have a Heroku account and a Phoenix application created.

Create an application on Heroku

In your application folder, create a Heroku app:

heroku create your-application-name --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git"

Remember that your name has to be unique on Heroku.

If you need to compile assets (JS, CSS, etc.) as part of your deployment (not needed i.e. for API apps), you will also need to add the phoenix-static buildpack:

heroku buildpacks:add https://github.com/gjaldon/heroku-buildpack-phoenix-static.git --app your-application-name

Configuration

Preparing the application for deployment

Modify your configuration files:

# config/prod.exs
config :heroku_phoenix, HerokuPhoenix.Endpoint,
  http: [port: {:system, "PORT"}],
  url: [scheme: "https", host: "your-application-name.herokuapp.com", port: 443],
  force_ssl: [rewrite_on: [:x_forwarded_proto]],
  cache_static_manifest: "priv/static/manifest.json",
  secret_key_base: System.get_env("SECRET_KEY_BASE")
# Configure your database
config :heroku_phoenix, HerokuPhoenix.Repo,
  adapter: Ecto.Adapters.Postgres,
  url: System.get_env("DATABASE_URL"),
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  ssl: true

Remember to replace your-application-name.herokuapp.com with your actual app name.

Change the websocket timeout so Phoenix will close them before Heroku does (55 seconds):

# web/channels/user_socket.ex
defmodule HerokuPhoenix.UserSocket do
  use Phoenix.Socket

  # ...

  transport :websocket, Phoenix.Transports.WebSocket,
    timeout: 45_000
end

Create Procfile in your project root directory to instruct the dyno how to start your app:

web: MIX_ENV=prod mix phoenix.server

Heroku configuration

Add a database to your Heroku app:

heroku addons:create heroku-postgresql:hobby-dev
# hobby-dev package allows for 20 open connections - we want 18 for our app server dyno so remaining 2 can be used by migrations or iex console:
heroku config:set POOL_SIZE=18

We also need to generate a secret key for Heroku:

heroku config:set SECRET_KEY_BASE=$(mix phoenix.gen.secret)

Deployment

Now you can push to the app to Heroku with git. Note: Heroku will only build from the master branch, to build from a different branch use:

git push heroku master:different_branch

After deployment is finished you just need to migrate the db:

heroku run "POOL_SIZE=2 mix ecto.migrate"

Useful commands

heroku logs (use --tail if you want to tail them) - check logs
heroku run "POOL_SIZE=2 iex -S mix" - enter to the console

Troubleshooting

In case of any compilation errors, try to force a build by adding elixir_buildpack.config file at the application root with the following content:

always_rebuild=true

We know all sorts of hints and tricks for configuring your software systems - and when we don’t have the answer we sure do love a challenge! If you would like to run your web application more effectively then make sure to get in contact with us at iRonin. We help business and software companies in the USA and around the world build faster, smoother, and more reliable systems.

Author's Bio
iRonin IT Team

Experts in software development

We are a 100% remote team of software development experts, providing web & mobile application development and DevOps services for international clients.

Similar articles
Comments

Bulletproof your development with remote team augmentation

Read how
This page is best viewed in portrait mode
Our websites and web services use cookies. We use cookies and collected data to enhance your experience, provide additional communication channels, improve marketing materials and enhance our offer. IRONIN SP. Z O.O. SP. K. is committed to protecting all the data that we collect or process in any way, especially data of personal nature. By accepting these terms you agree to our usage of cookies and processing your data, according to our Privacy Policy, and you declare that your browser settings reflect your preferences. Read more You have the right to revoke this agreement at any time, based on the terms of our Privacy Policy. You can change cookies settings in your browser. If you do not agree with us using cookies and processing your data, please change your cookies settings in your web browser and reject these terms. You can find more information about cookies, your data privacy This site uses cookies. By continuing to browse the site, you are agreeing to our use of cookies. data processing, and your rights in our Privacy Policy.