Elixir Releases: Switching App Version

Since version 1.9 Elixir’s Mix has got a new command that helps building Erlang releases. It’s usage is straightforward and well documented, but one thing that deployments using releases brings, is the possibility to fallback to any earlier version of the app that has been released, this feature did not get much love in the docs or around the Internet.

The documentation mentions following environment variable:

RELEASE_VSN – the version of the release, otherwise the latest version is used. It can be set to a custom value when invoking the release. The custom value must be an existing release version in the releases/ directory

That means when starting the app we can set that variable to any existing release version (releases directory contains all of them and can be used as reference) to run that specific version, everything is bundled, so in most cases that would even use older runtime version when needed.

If our release runs in prod environment and is named “live” then the commands from the project root might look like that: _build/prod/rel/live/bin/live start starts the default (latest) version and RELEASE_VSN=0.0.1 _build/prod/rel/live/bin/live would start the version 0.0.1 of the app (that must have been built at some point earlier) even if that’s not the last version. The ls _build/prod/rel/live/releases/ would list all the versions that are available.

One thing to keep in mind is that if you use Systemd to manage the application on the OS level and would try the same there (e.g. RELEASE_VSN=0.0.1 sudo systemctl start myapp.service) that wouldn’t work, Systemd would just ignore the variable. The reason: Systemd deals with different life-cycle stages of the operating system and the variables are loaded at different points of time so relying on them would do more harm then good.

To make a variable known to Systemd a separate systemctl command should be used, for the above example it would be sudo systemctl set-environment RELEASE_VSN=0.0.1. After running this command, the variable is set and will be seen by the services, so starting / restarting it (sudo systemctl restart myapp.service) will activate the needed version. To reset the variable and fall back to the latest version, just unset it like that: sudo systemctl unset-environment RELEASE_VSN.