Given an umbrella application with applications that define their own runtime.exs
files in apps/appname/config/runtime.exs
. The app specific config files are added to the releases using Config Providers. Is it possible to also load those app-specific runtime.exs
files in development? Can I pass an arg to iex -S mix
or something?
Given an umbrella application with applications that define their own
runtime.exs
files inapps/appname/config/runtime.exs
Context:
When I created my own umbrella project, (e.g. mix phx.new --umbrella
) , the directory structure ended up something like the following.
my_app_umbrella
├── README.md
├── apps
│ ├── my_app
│ └── my_app_web
├── config
│ ├── config.exs
│ ├── dev.exs
│ ├── prod.exs
│ ├── runtime.exs
│ └── test.exs
└── mix.exs
And trying any sort of import_config
inside config/runtime.exs
looks to be forbidden
import_config "../apps/my_app/config/runtime.exs"
or if I have config/my_app/runtime.exs
closer to the config files in the umbrella app itself:
import_config "my_app/config/runtime.exs"
% iex -S mix
** (RuntimeError) import_config/1 is not enabled for this configuration file. Some configuration files do not allow importing other files as they are often copied to external systems
(elixir 1.16.2) lib/config.ex:312: Config.import_config!/3
/Users/ben/my_app_umbrella/config/runtime.exs:112: (file)
(stdlib 5.2) erl_eval.erl:750: :erl_eval.do_apply/7
(stdlib 5.2) erl_eval.erl:136: :erl_eval.exprs/6
(elixir 1.16.2) lib/code.ex:572: Code.validated_eval_string/3
I had assumed that for umbrella applications, the way it does releases, to place all config in this runtime.exs
.
The app specific config files are added to the releases using Config Providers.
Can you provide some additional context about how your Config Providers work?
I borrowed the below from here. I have very little in the app specific configs. Just the things that clash, e.g. swoosh and sentry.
defp releases do
target = target()
[
localapp: [
include_executables_for: executables(target),
applications: [runtime_tools: :permanent, localapp: :permanent],
steps: steps(target),
rel_templates_path: "apps/localapp/rel"
],
cloudapp: [
include_executables_for: [:unix],
applications: [runtime_tools: :permanent, cloudapp: :permanent],
steps: steps(:unix),
rel_templates_path: "apps/cloudapp/rel",
config_providers: config_providers_for_apps([:cloudapp])
]
]
end
# Add the runtime.exs configuration for each provided app
defp config_providers_for_apps(apps) do
for app <- apps do
{Config.Reader,
path: {:system, "RELEASE_ROOT", "/apps/#{app}/config/runtime.exs"}, env: Mix.env()}
end
end
# When assembling the release, we copy all the runtime.exs files defined in `config_providers` to it,
# keeping the relative app path to avoid collisions.
defp copy_configs(%Mix.Release{path: release_dir, config_providers: config_providers} = release) do
for {_module, path: {_context, _root, config_file_path}, env: _} <- config_providers do
config_dir = Path.join(release_dir, Path.dirname(config_file_path))
# Clean the config directory to make sure we are only including the files defined in the config_providers
File.rm_rf!(config_dir)
File.mkdir_p!(config_dir)
File.cp!(
Path.relative(config_file_path),
Path.join(config_dir, Path.basename(config_file_path))
)
end
release
end