Elixir 1.9.1 Releases
This is a short introduction to creating releases with Elixir 1.9.1+ which contains built-in tooling for releases.
A release is a bundle of the runtime and pre-compiled code, and a set of configurations more suitible for production (like running in embedded mode).
On top of that, Elixir’s new built-in release handling adds some much needed tools for runtime configuration for releases, something that has been a pain in the past, with tools like relx.
§Creating a Release
In 1.9.1+ creating a release is super easy. You can ask mix to generate some release configuration files for you:
$ mix release.init
and create a release with
$ mix release
which will generate a release in (by default)
_build/dev/rel/<release>
To create a production release
MIX_ENV=prod mix release
which will output a release in
_build/prod/rel/<release>
You can now tar the release folder and move it to your target system.
§Running a Release
I’ve created an example project with mix new --sup
and changed my application controller to:
1defmodule ReleaseExample.Application do
2 use Application
3
4 def start(_type, _args) do
5 IO.puts("Hello Release")
6 opts = [strategy: :one_for_one, name: ReleaseExample.Supervisor]
7 Supervisor.start_link([], opts)
8 end
9end
And created a dev release with mix release
.
Now let’s try and start it:
$ _build/dev/rel/release_example/bin/release_example start
Hello Release
Great, it works.
You can also start it with an iex shell with
$ _build/dev/rel/release_example/bin/release_example start_iex
Erlang/OTP 22 [erts-10.4.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Hello Release
Interactive Elixir (1.9.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(release_example@tbugsgnmbp)1>
but in a production system you are better of running the regular start
command
as a service (with systemd
, in a container, or however you normally run services)
and connect to it with a remote shell:
# shell 1
$ _build/dev/rel/release_example/bin/release_example start
Hello Release
# shell 2
$ _build/dev/rel/release_example/bin/release_example remote
Erlang/OTP 22 [erts-10.4.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
Interactive Elixir (1.9.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(release_example@tbugsgnmbp)1>
§Configuration
Configuration works like normal.
config/config.exs
is the compile-time configuration you use to configure
things you know beforehand.
Releases also gives you the option to do runtime configuration with
config/releases.exs
.
This file is evaluated at each application boot. A few rules must be followed for this to work. From the docs:
- It MUST import Config at the top instead of the deprecated use Mix.Config
- It MUST NOT import any other configuration file via import_file
- It MUST NOT access Mix in any way, as Mix is a build tool and it not available inside releases
This is a valid config/releases.exs
file:
import Config
config :my_app, :secret_key, System.fetch_env!("MY_APP_SECRET_KEY")
See Application Configuration for details.
Releases can do a lot more than what I’ve shown, and has a bunch of options for customization, like bundling extra files into the release, adding custom start and stop scripts, configure the VM, cut a subset of your umbrella project as a release, hot code upgrade, and a bunch more.
It’s by far the best way to package your Elixir applications and you should use it.
Check out the release documentation for a more detailed walkthrough.