Setting for apps behind a load balancer


I’m trying to understand better how to configure the app for production. My DevOps skills are somewhat limited, so bare with me if I write something dumb :slight_smile:

We have the following setup:

  • Domain:
  • There is a load balancer, which proxy passes to the app on port 4000
  • The app has an internal DNS name.

Now, I’m wondering what the correct setting is:

In production.exs we have this:

config :super_app, SuperAppWeb.Endpoint,
  # This is critical for ensuring web-sockets properly authorize.
  url: [host: "localhost", port: 4000]

What is the correct setting here? Should put the public domain in there? I’m 99% sure that yes, but want to double check.

The url config is used by Phoenix to generate any public facing URLs. So this must be indeed your public domain name. In a similar fashion, I have the following config for my Phoenix app on Heroku (and thus also serving behind a load balancer);

config :example, ExampleWeb.Endpoint,
  url: [scheme: "https", host: System.fetch_env!("HOST"), port: 443],
  http: [port: String.to_integer(System.get_env("PORT", "4000"))]

The HOST option is my domain name and I only configure the PORT on which Phoenix’s server listens to.


Assuming the LB terminates TLS: don’t forget to make your Phoenix app aware that requests were actually made over HTTPS, based on the X-Forwarded-Proto (or similar) header. Otherwise Plug.Session will believe the request was made over HTTP and won’t set the ‘secure’ flag on session cookies (which would be bad).

The force_ssl endpoint option can be used for that, as explained here and here.


If the LB forwards the HOST header it will be taken from the conn and doesn’t need to be hardcoded in the config.