I have an application that needs to run under 2 different name/configuration on the same box. I have read the mix release documentation but I can’t figure out how I can do this. For dynamic configuration, it says that I need to create a config/releases.exs file as such:
import Config
config :my_app, :secret_key, System.fetch_env!("MY_APP_SECRET_KEY")
However I have some config value that I cannot be put in an environment variable, is there a way to have a config.exs file per application name
on the target machine ?
Here’s my mix.exs project section.
def project do
[
app: :my_app,
version: "0.1.0",
elixir: "~> 1.9",
start_permanent: Mix.env() == :prod,
deps: deps(),
releases: [
as: [
include_executables_for: [:unix],
applications: [runtime_tools: :permanent]
],
vs: [
include_executables_for: [:unix],
applications: [runtime_tools: :permanent]
]
]
]
end
I would like to have different runtime config for the as
and vs
app names.
I understand you are trying to get your app’s name depending on context in order to achieve a different runtime behavior. Maybe you could use a new ENV variable that dictates how you app is named? For example:
def project do
[
app: get_app_name(),
]
end
defp get_app_name do
case System.fetch!("SOME_VAR") do
"bananas" -> :hello
"oranges" -> :world
_ -> :default
end
end
If you cannot, by any means, use ENV variables at all, then I suggest your go for an alternative approach since afaik, it is not possible to have a mix.exs
file per app name, since OTP apps are only allowed to have 1 name during runtime.
You can use runtime_config_path
(mentioned in the docs here). You can also access all environment variables, include RELEASE_NAME
, inside the script itself: https://hexdocs.pm/mix/Mix.Tasks.Release.html#module-environment-variables
2 Likes
@josevalim if understand, the config file will be copied as is to the release, so it needs to be on the build box. I wished that there was a way to have the config file only located on the target system. If I understand there is no direct way of doing this for the moment.
This can cause me some issue since I would like our sys admins to be able to change the configuration on the target system without needing to generate a new release.
For the moment, In order to avoid storing my secrets into my source control, I will use a combination of environment variable and the use of the runtime_config_path
variable.
Because the config script is regular Elixir code, you can have the config/releases.exs
execute another config file (or load any other file) that your devops/admin team will change.
For example:
release_root = System.fetch_env!("RELEASE_ROOT")
for {application, kv} <- Config.Reader.read!(Path.join(release_root, "config.exs")),
{key, value} <- kv do
config application, key, value
end
4 Likes