Run a Phoenix 1.6 application on Scalingo using Releases

In this post, we will show you how to run a Phoenix application on Scalingo using Releases. Whether you want to migrate your Phoenix application away from Heroku or need to upgrade your Scalingo stack from scalingo-18 to scalingo-20, the following guide should help.

We will start with a simple Phoenix 1.6 application that uses esbuild. We will gradually increase the complexity by adding npm and custom apt packages.

  1. Deploy a simple Phoenix 1.6 application using esbuild
  2. Deploy a simple Phoenix 1.6 application using esbuild and npm
  3. Set environment variables
  4. Bonus: How to install apt packages, such as cmake

Deploy a Phoenix 1.6 application using Releases with esbuild

Under the hood, we will use mix phx.gen.release to create a release.

In short, we will need to add four files to our repository:

.buildpacks

In .buildpacks, we will have to define the community buildpack that helps Scalingo to detect our Elixir application. Unfortunately, the buildpack mentioned in Scalingo’s docs does not support scalingo-20. For now, you can use this fork:

https://github.com/nwittstruck/heroku-buildpack-elixir#scalingo

We will update the post once the pull request has been merged.

elixir_buildpack.config

The elixir_buildpack.config specifies the elixir and erlang versions used in your project. Set them, as well as the release parameter.

To compile our assets, we will us a pre compile hook. esbuild, you can just set release to true and use a pre-compile hook to use esbuild to compile all assets.

Hint: If you are deploying an application without assets, e.g. an API service, it is enough to set release to true. You can then skip the pre-compile hook and the compilation script.

Hint: If you need npm, see the next section on how to do this.

elixir_version=1.13.4
erlang_version=25.1
release=true
hook_pre_compile="./compile-assets"

See here for a detailed list of configuration parameters.

compile-assets

Before building a release, we need to run esbuild to build the assets. This is what we do in the following script.

Hint: Please adjust the examples for your needs and move it to a proper location.

#!/bin/bash
mix assets.deploy
mix phx.digest
mix phx.digest.clean

Procfile

The Procfile specifies the commands that should be executed to run the app, see https://doc.scalingo.com/platform/app/procfile. It is exactly like the Procfile used on Heroku. In case of a Phoenix application, the project should contains a file named Procfile in the project root directory. The file Procfile should have the following content:

web: bash _build/prod/rel/<your application>/bin/server

Phoenix 1.6 + esbuild + npm

If you need npm in your pipeline, the approach with the pre-compile hook will not work. You will have to add additional buildpacks to install nodejs. Due to this, we can no longer use the release command provided by the elixir buildpack. We will combine three buildpacks:

  1. for elixir: heroku-buildpack-elixir, patched for scalingo
  2. for nodejs: heroku-buildpack-phoenix-static
  3. for phoenix release support: heroku-buildpack-elixir-mix-release

We will end up with five files:

.buildpacks

Therefore, we need to change our .buildpacks:

https://github.com/nwittstruck/heroku-buildpack-elixir#scalingo
https://github.com/gjaldon/heroku-buildpack-phoenix-static
https://github.com/chrismcg/heroku-buildpack-elixir-mix-release

elixir_buildpack.config

And elixir_buildpack.config

elixir_version=1.13.4
erlang_version=25.1
release=false

Delete your script ./compile-assets as you no longer need this. Instead, heroku-buildpack-phoenix-static defines a compile script called compile, which works slightly different:

phoenix_static_buildpack.config

# We can change path that npm dependencies are in relation to phoenix app. E.g. assets for phoenix 1.3 support.
assets_path=./assets
node_version=14.16.0
npm_version=6.14.11
phoenix_ex=phx

See here for a full list of configration parameters.

compile

#!/bin/bash

cd $phoenix_dir

# Compile assets
mix assets.deploy

mix phx.digest

if mix help phx.digest.clean 1>/dev/null 2>&1; then
  mix phx.digest.clean
fi

Procfile

The Procfile stays the same:

web: bash _build/prod/rel/<your application>/bin/server

Set environment variables:

To actually run the application, you will need to specify environment variables.

For a typical phoenix application, you will need to specify at least the env vars DATABASE_URL and SECRET_KEY_BASE. It is possible to define an alias the DATABASE_URL to the variable provided by Scalingo, that points to your database container.

You will need to deploy the database container manually.

Depending on your database container size, adjust the POOL_SIZE as well. For the free tier, you will need to set the POOL_SIZE to 1.

Bonus points: How to add additional packages, such as cmake?

This can be done with another buildpack:

.buildpacks

Just add the Scalingo buildpack for apt:

....
https://github.com/Scalingo/apt-buildpack.git

Aptfile

And define the additional apt packages in your Aptfile:

cmake

Need additional help? Contact us!

B310 Digital GmbH, c/o FLEET7, Fleethörn 7, 24103 Kiel hi@b310.de