I’m using runtime.exs
as a way to overwrite config variables (compile time) by environment variables (runtime).
This works.
However, before the application starts: I run _build/prod/rel/production/bin/production eval "MyApp.ReleaseTasks"
.
defmodule JackJoe.ReleaseTasks do
alias Ecto.Migrator
require Logger
@start_apps [:crypto, :ssl, :myxql, :ecto, :ecto_sql]
@app :justified
def migrate_and_seed do
Logger.info("|> MIGRATE_AND_SEED")
start_services()
run_migrate()
run_seed()
stop_services()
end
def migrate do
Logger.info("|> MIGRATE")
start_services()
run_migrate()
stop_services()
end
def seed do
Logger.info("|> SEED")
start_services()
run_seed()
stop_services()
end
# def rollback(repo, version) do
# IO.puts("|> ROLLBACK")
# start_services()
# {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
# stop_services()
# end
def run_migrate do
for repo <- repos() do
{:ok, _, _} = Migrator.with_repo(repo, &Migrator.run(&1, :up, all: true))
end
end
def run_seed, do: Enum.each(repos(), &run_seeds_for/1)
#################
defp start_services do
Logger.info("|> Starting dependencies...")
# Start apps necessary for executing migrations
Enum.each(@start_apps, &Application.ensure_all_started/1)
Application.load(@app)
# Start the Repo(s) for app
Logger.info("|> Starting repos...")
# Switch pool_size to 2 for ecto > 3.0
Enum.each(repos(), & &1.start_link(pool_size: 2))
end
defp stop_services do
Logger.info("|> Success!")
:init.stop()
end
defp run_seeds_for(repo) do
# Run the seed script if it exists
seed_script = priv_path_for(repo, "seeds.exs")
if File.exists?(seed_script) do
Logger.info("|> Running seed script...")
Code.eval_file(seed_script)
end
end
defp repos, do: Application.get_env(@app, :ecto_repos)
defp priv_path_for(repo, filename) do
app = Keyword.get(repo.config, :otp_app)
repo_underscore =
repo
|> Module.split()
|> List.last()
|> Macro.underscore()
Path.join(["#{:code.priv_dir(app)}", repo_underscore, filename])
end
end
This tasks lacks the overwritten variables from runtime.exs
.
import Config
# Settings at runtime for demo apps
IO.inspect("Runtime config")
IO.inspect(System.get_env())
IO.inspect(Application.get_all_env(:my_app))
if Application.get_env(:my_app, :deploy_env) in ["demo"] do
IO.inspect("Setting runtime config")
config :my_app, MyApp.Repo, database: System.fetch_env!("DB_NAME")
config :my_app, MyAppWeb.Endpoint,
url: [host: System.fetch_env!("HOST"), scheme: "https", port: 443]
config :my_app,
cookie_domain: System.fetch_env!("COOKIE_DOMAIN")
IO.inspect(Application.get_all_env(:my_app))
end
If I inspect the runtime.exs
when just starting the application I can clearly see all environment variables and the config from my Application before and after (overwritten).
When running the eval
command, the environment variables are printed, but Application.get_all_env(:my_app)
results in []
. And as a consequence, the migration fails because database is not set.