Skip to content

Instantly share code, notes, and snippets.

@theoretick
Last active December 24, 2016 17:30
Show Gist options
  • Save theoretick/9b6d91bacac921846faa to your computer and use it in GitHub Desktop.
Save theoretick/9b6d91bacac921846faa to your computer and use it in GitHub Desktop.
Notes on deploying elixir, erlang, and OTP apps with exrm and conform

Notes on deploying Elixir, Erlang, and OTP apps with exrm and conform



how exrm generates a release (with conform)

exrm adds a Mix task called mix release to your project. To build a production release, you just run MIX_ENV=prod mix release (after the usual build cycle). This step creates an Erlang release tarball, which contains everything needed to run your app.

Inside the release is a sys.config file (releases/<version>/sys.config). Application.get_env/3 will consult this file when your code is deployed.

sys.config comes from erlang and is standard OTP configuration for your apps.

Using mix release out-of-the-box will convert your config/config.exs into a sys.config file.

conform allows you to place .conf files inside your release for configuration management and automatically builds a new sys.config each time you start your app using bin/my_app start. It uses an escript execution to do this.

why conform?

If not using conform and relying entirely off config.exs, you cannot use dynamic code relying on the runtime environment, e.g.

config :foo,
  bar: System.get_env("FOOBAR")

The reason for this is that the Erlang VM uses sys.config for configuration, and sys.config can only contain static terms, not function calls or other dynamic code. When your config.exs is evaluated and converted to sys.config, the dynamic code in config.exs is executed, evaluated, and the result is persisted in sys.config. If you are relying on such things as environment variables in config.exs, the value stored in sys.config will be the value of those variables when the build was produced, not their values when the release is booted, which is almost certainly not what you intended. 1

how conform uses *.conf and schema

when running releases/rel_name/bin/rel_name console, conform is executed to transform the .conf file(s) into a config datastructure, which is then merged over the top of the config in config.exs.

The schema is used to convert the .conf values to a more useful form (this is what the datatype option is for).

configuration is merged over config.exs settings, so they can co-exist

Conform steps

  1. Parse .conf
  2. Perform mapping & validations on .conf using .schema.exs 2b. (execute any transforms on mapping)
  3. Merges parsed config OVER config.exs/sys.config
  4. outputs sys.config containing final configuration

conform also supports a custom vm.args file. vm.args is the standard erlang file that defines which args are passed when firing up the erlang VM, e.g. setting otp app's node name: -name appfoo@127.0.0.1 and cookie: -setcookie appfoo).

exrm can override both vm.args and sys.config if desired. 1


exrm's mix release cycle (build on relx -> erlang release mgmt)

2

  1. read configuration
  2. generate relx.config, sys.config, vm.args, etcs
  3. run before_release hooks
  4. (relx) perform discovery (apps, previous releases)
  5. (relx) resolve dependencies
  6. (relx) build release
  7. (relx) output release to <project>/releases
  8. runs after_release hooks
  9. repackages release
  10. runs after_package hooks

Terminology

  • Release - a set of versioned OTP applications
  • ERTS - Erlang Runtime System
  • Release Metadata - app startup order, etc
  • Explicit configuration - sys.config, vm.args

Sources

Footnotes

  1. https://github.com/bitwalker/exrm/blob/5e3d0506f69fa3838207d5a5eb76d4608e63ba62/docs/release_configuration.md 2

  2. http://slides.com/paulschoenfelder/elixirconf2015-release-management#/5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment