Elixir Mix Release: Enforcing Compile‑Time‑Only Configuration Keys
0 reputation · 22 Apr 2024, 14:45 UTC
0 reputation · 22 Apr 2024, 14:45 UTC
When building an Elixir release with mix release, the values in config.exs are baked into the generated sys.config file. At runtime, any configuration key can still be overridden by an environment variable accessed via System.get_env/2. This overlap makes it difficult to guarantee that certain keys remain immutable after the release is created.
The goal is to establish a clear permission boundary so that specific configuration keys are treated as compile‑time only and cannot be altered by the host environment. Currently the Mix release documentation does not provide a mechanism to declare such a boundary, leaving developers to rely on conventions that may be missed during troubleshooting.
What options exist, if any, to enforce compile‑time‑only semantics for a configuration key in a Mix release? If no built‑in option is available, which patterns or conventions can be adopted to prevent accidental runtime overrides? How can a developer verify at runtime that a particular setting originated from the baked‑in sys.config rather than an environment variable?
From OTP 25 onward, mix release supports a persistent: true flag on any configuration entry. This flag causes the key to be baked into sys.config and blocks overrides from System.get_env/2 or Application.put_env/3 at runtime. If you are on an older OTP, there is no built‑in enforcement; you must rely on conventions and runtime checks.
config/config.exs (or any config file that runs at compile time), add the persistent: true option to the key:config :my_app, :secret_key, "super‑secret", persistent: true
mix release. The generated _build/*/rel/my_app/releases/*/sys.config will contain an entry similar to:[{my_app, [{secret_key, "super‑secret"}]}]
sys.config and any attempt to override it via an environment variable or Application.put_env/3 will raise an error.export MY_APP_SECRET_KEY=env‑value
Start the release and check the value:
iex -S mix
iex> Application.get_env(:my_app, :secret_key)
"super‑secret"
If the output matches the baked value, persistence is working.
Application.put_env(:my_app, :secret_key, "new‑value")
# => ** (ArgumentError) cannot overwrite persistent key :secret_key
This confirms the key is protected.
sys.config – Open the file in _build/*/rel/my_app/releases/*/sys.config and verify that the key appears only once and is not overridden by any env section.
MyApp.Config) and never read System.get_env/2 for those keys.config/*.exs and never in config/runtime.exs or via --env flags.Application.put_env/3 calls.To tailor the recommendation precisely, could you confirm which OTP version you are targeting for the release?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.