Issue with deployment to AWS ECS: System.get_env/1 in prod.exs not retrieving environment variable defined in Task definition

Hello, I’m new to AWS deployment and facing an issue with my Elixir/Phoenix application.

I’ve deployed my app to AWS ECS, but I’m encountering a problem with environment variables.

All the configurations in prod.exs that fetch values from environment variables using System.get_env() are returning nil.

In my prod.exs file:

config :my_app, :my_variable, System.get_env("MY_VARIABLE")
...

And in my module:

defmodule MyApp.MyModule do
  @my_variable Application.compile_env(:my_app, :my_variable)

  def get_variable, do: Application.get_env(:my_app, :my_variable)
  ...
end

Both of these methods return nil.

However, strangely, System.get_env("DATABASE_URL") in runtime.exs works fine (the app won’t function without a database connection). This indicates that the app can read the environment variables defined in the Task Definition.

Now, I’m confused about how runtime and compile time handle environment variables. How can I resolve this issue in my case? Where should I place my configurations? When should I inject environment variables for compile time?

Should I move all the configurations to runtime.exs and stop using Application.compile_env/2 ?

Help me please.

It depends when that variable is being set? If its after you build it then yeah putting it in runtime.exs would be best and then using Application.fetch_env!/2.

This is a common mistake.
The config in prod.exs is set during compilation, so any environment variables you fetch will be at the value they have during compilation.
runtime.exs was added specifically for this situation, it’s run as a script when your app boots.
This allows you to fetch info from the environment and add it to your config.
There is one caveat, runtime.exs is run for all your environments, so not only for :prod, this is why you’ll see the code inside an if block to check for the correct environment.

2 Likes