What is the difference between using {:system, "PORT"} and System.get_env("PORT") in deployment?

You cannot make it code reload friendly with the API above. The endpoint is a supervisor and we need to redefine the supervision tree in case the user wants to start listening to a new port or change any stateful configuration. And in order to do so with code reloading, it is only possible if you do so inside init. Any value you pass through start_link will be permanently sticked and not code reloadable.

If you take a step back and ask: where is the best way to configure a supervisor so I can change its children under code reloading, the answer is going to be on init. This is very aligned with the child_spec discussion happening on elixir-lang-core right now.

I believe though it is still worth debating if we should rely less on the application environment, although the need of per environment configuration is almost a given for Ecto and Phoenix. Calling Ecto.start_link(Repo) instead of Repo.start_link() can also be an improvement, so we stop injecting start_link everywhere, but will likely become irrelevant if the child_spec proposal is accepted, since nobody will call Repo.start_link directly anymore and then we will be free to move it elsewhere.

1 Like