Elixir configuration can be placed in several different files. Config is often stored in config/config.exs
and often config.exs
is setup to load environment specific configuration files like config/test.exs
, config/prod.exs
, and so on. And now in Elixir 1.9 runtime configuration can be placed in config/releases.exs
.
Configuration Evaluation
These various configuration files are evaluated at different times. config/config.exs
is evaluated at compile time. Runtime configuration in config/releases.exs
is evaluated inside the release at runtime.
Configuration Merging
If we use multiple configuration files configuration data is merged recursively. We can observe how this merging works by specifying multiple configurations in the same configuration file with the same root key and then loading the configuration values from it.
# Write this to a file named config_test.exs
import Mix.Config
config :config_test,
param1: :some_value,
param2: :another_value,
nested_param: [keyword: :list]
config :config_test, :nested_param, [another: :keyword]
config :config_test,
param1: :new_value
This file makes three config
calls to set the configuration for the :config_test
application. These config
calls will be evaluated in the order they are defined in the file, but what will the final configuration be?
Loading the configuration using Config.Reader
in the iex shell shows us the final values:
iex> Config.Reader.read!("config_test.exs")
[
config_test: [
param1: :new_value,
param2: :another_value,
nested_param: [keyword: :list, another: :keyword],
]
]
Config.Reader
recursively merges the configurations in order until they are all combined.
The first config
call defines the base configuration. The third changes the value of the :param1
key to :new_value
. Even keys inside :nested_param
keyword list get merged with the existing keyword list. We can also see that the whole configuration itself is just a set of nested keyword lists.
Conclusion
Elixir merges configuration spread across multiple files in a reasonable way, and makes it easy to combine configuration from config/config.exs
, config/releases.exs
, and any other file containing configuration data without having to duplicate any of the keys and values.
But remember, configuration files aren’t always best. Application configuration is global and therefore prevents libraries and applications from being used with different configurations in the same release. Avoiding configuration files entirely is usually the best approach for library applications.
Another important change related to configuration is that mix new will no longer generate a config/config.exs file. Relying on configuration is undesired for most libraries and the generated config files pushed library authors in the wrong direction.