Set Application.env before all dependent appllications are started

An application (app1) depends on another application (app0).

 def application do
[
  mod: {App1, []},
  applications: [
     "app0"
  ]
]

app0 reads configuration from Application.get_env during its startup.

I need to change the environment at the startup of app1, from runtime information (typically, OS environment variables.)

How can I do that ?

  • can I explicitely change the order of application startup ? How will it play with “automatic” dependencies discovery ?
  • should I edit the app0 to read from os itself ? I’m concerned I’ll have to do this for application that I don’t master
  • my applications are released using distillery, so specifying “System.env” in a config.exs file is not an option, since it would use the OS env variable from build time and hardocde them in the delivered artifact.

If app1 depends on app0 it will be started thereafter.

But what or which environment do you want to change during the start of app0? Or do you wan’t to alter app0s environment during the startup of app1? If the latter is true, why not just use config.exs?

Hum, no, in my case, app1 depends on app0, and (quite logically ?) app0 is started first. (Maybe I’m not clear about what I mean by “depends on” ? I mean app0 appears in deps and applications in the mix.exs of app1)

It happens that app0 reads part of its configuration with Application.get_env.

In dev environment, I can put this variable in the config.exs of app1, and it will work.

However, in production, I can not do this, since the right value it will only be known at runtime (from OS environment variable.)

Use Distillery’s run-time configuration and REPLACE_OS_VARS - you can set environment variables in your deployment config.exs that reads like "${MY_VAR_NAME}".

Using Distillery, we’re converging on three environments: a dev environment, a test environment, both of which can use System.get_environment in the configurations, and a deploy environment that is built with Distillery and configured through REPLACE_OS_VARS - whether that thing is deployed to staging, production, load test, … is then defined 12factor style with environment variables.

(for completeness, there’s also a ton of hooks in the Erlang VM startup, start reading here if you’re interested, which would potentially allow you to do stuff before dependent apps are loaded, but for all practical purposes, the above works just fine)