One of the major differences between running your application as a release and as a Mix project is the differences in configuration. Mix evaluates the configuration right before the application starts, releases evaluates the configuration when your application is compiled.
This implies in a large mismatch of how those two environments are used. For releases, environment variables (read by `System.get_env/1`) need to be set when the application is compiled and such information may not be available at this point.
Ideally, we would want a release to evaluate the configurations files in `config` when the release starts. One approach would be to copy the configuration files as is to the release but that's hard to achieve in practice for two reasons:
1. A config file may import other config files and often importing those files happen dynamically. For example: `import_config "#{Mix.env()}.exs"`. The dynamic import makes it hard for release tools to know which configuration files must be copied to a release, especially in cases like umbrella projects, where a developer may load configuration across projects
2. Even we copy today's configuration files to a release, those configuration files rely on `Mix`, which is a build tool and therefore it is not available during releases
To solve those issues, we need to make sure we can discover all imports of a configuration file without evaluating its contents. We also need to introduce a new module for configuration that does not depend on Mix.
This is the goal of this proposal.
## Application.Config
This proposal is about introducing a module named `Application.Config`. It will work similarly to the existing `Mix.Config`, except it belongs to the `:elixir` application instead of `:mix`. This allows releases to leverage configuration without depending on Mix.
The user API of `Application.Config` is quite similar to `Mix.Config`. There is `config/2` and `config/3` to define configurations. There still is `import_config/1` to import new configuration files with one important difference: the argument to `import_config/1` must be a literal string. So interpolation, variables or any other dynamic pattern is no longer allowed.
In order to help with configuration management, we will introduce a project option in your `mix.exs`, named `:config_paths` to help manage multiple required and optional configuration files.
In the next section we will provide an example of how configuration files used by projects like Nerves and Phoenix will have to be rewritten and then we will discuss how integration with release tools such as distillery will work.
### A common example
Projects like Nerves and Phoenix generate files with built-in multi-environment configuration. Today, this configuration has an entry point `config/config.exs` file that imports an environment specific configuration at the bottom: