Elixir Releases for Prod
Elixir releases for prod
Suyash Singh
Posted by Suyash Singh
on October 29, 2022
Photo by James on Unsplash

This post is a guide on how to deploy and self host elixir phoenix applications with ease. The steps mentioned in this guide can also be applied to build containers & images if need be, else the guide on hex docs for container based releases is very easy to follow as well.

This post assumes that you have a dedicated build server in your release pipeline.

Step 1 — Install Erlang + Elixir on the build server

To build, test, deploy we would require both Erlang and Elixir on the build server. Once we have generated an elixir release the binary can be started independent of the build server environment as long as the target machine has the same architecture as the build server.

$ sudo apt-get install erlang elixir

This step assumes that we are running ubuntu just for example’s sake. Follow the steps mentioned on the official installation guide to install more recent versions.

Step 2 — Install Hex & Rebar

Mix is the build automation tool for elixir applications and like mix, rebar is the tool used by erlang for build lifecycle related activities. Hex is the package manager used by both mix and rebar. We would utilize hex to fetch and manage dependencies for our application.

$ mix local.hex
$ mix local.rebar

Step 3 — Install app dependencies

$ mix deps.get
$ mix deps.get --only prod

Step 4 — Compile

Now, we want to generate binaries out of our source code. And, if we have used any javascript related technologies in our app we must build and process them as well using mix assets.deploy.

$ MIX_ENV=prod mix compile
$ MIX_ENV=prod mix assets.deploy

Step 5 — Generate phoenix release

Finally, we want to create the artifacts we can deploy to the target deployment servers.

$ mix phx.gen.release
$ MIX_ENV=prod mix release

Step 5.1 — Deploy the artifacts to the target machine

Bundle up the release artifacts and deploy it to the production environment where we would be running our phoenix applications.

Step 6 — Setup Environment variables on the target machine

Elixir Phoenix applications offers the following ways to manage sensitive information essential for running the applications:

Build time configurations

Runtime environment variables using config/runtime.exs

Follow the official guide to understand more about what would suit your need. Here, we are going with the runtime environment variables approach. The official guide states the following for secrets management in elixir applications:

All Phoenix applications have data that must be kept secure, for example, the username and password for your production database, and the secret Phoenix uses to sign and encrypt important information. The general recommendation is to keep those in environment variables and load them into your application. This is done in config/runtime.exs (formerly config/prod.secret.exs or config/releases.exs), which is responsible for loading secrets and configuration from environment variables.

Therefore, you need to make sure the proper relevant variables are set in production:

$ mix phx.gen.secret
<<OUR_SECRET_KEY>>
$ export PORT=<<OUR_APP_PORT>>
$ export SECRET_KEY_BASE=<<OUR_SECRET_KEY>>
$ export DATABASE_URL=ecto://<<OUR_DB_USER>>:<<YOUR_DB_PASS>>@<<OUR_HOST>>/<<OUR_DB>>
$ export PHX_HOST=<<OUR_PHX_HOST>>

And, now whenever we start our phoenix server it will pick up these environment variables. config/runtime.exs is the recommended place where you should ideally setup the input parameters your application would require from the host machine at the time of server startup.

Step 7 — Start

$ _build/prod/rel/<<your_app>>/bin/server

Conclusion

After following these steps, our phoenix server should be up & running on the port specified. In future posts we will see how we can do hot deployments for our elixir applications.