What is the difference between the port numbers provided in prod.exs and prod.secret.exs?

In a default Phoenix 1.4.12 app I have the following config in prod.exs

config :myapp, MyappWeb.Endpoint,
  url: [host: "example.com", port: 80],
  cache_static_manifest: "priv/static/cache_manifest.json"

and the following config in prod.secret.exs

config :myapp, MyappWeb.Endpoint,
  http: [
    port: String.to_integer(System.get_env("PORT") || "4000"),
    transport_options: [socket_opts: [:inet6]]
  ],
  secret_key_base: secret_key_base
  1. What is the difference in the port nos. 80 & 4000 ? Where will my app run in prod - 80 or 4000 ?
  2. Do I need to change the host example.com? What if I dont have any domain registrered yet?

Trying to answer your question based on the hexdocs.pm documentation from phoenix to see at the same time if it’s able to answer your question or that we need to add more or a better explanation :slight_smile:
So the first one is port that exists in the url key of the endpoint configuration:

:url - configuration for generating URLs throughout the app.

The second port is the one in the http key of the endpoint configuration:

:http - the configuration for the HTTP server. Currently uses Cowboy and accepts all options as defined by Plug.Cowboy

where in above line Plug.Cowboy references this hexdoc stating:

:port - the port to run the server. Defaults to 4000 (http) and 4040 (https). Must be 0 when :ip is a {:local, path} tuple.

So we have url-port and http-port, the first one, url-port is for generating urls, so if you use a helper somewhere page_url() then it will use that port to generate the url. http-port is used for starting the actual server on that port.

It’s mostly used for when you’re hosting behind a load balancer, that the internal http-port is not the same as the external port for your clients. (that is: the app runs on port 4000 behind a load balancer which serves the pages at port 443 (https) or port 80 (http) to the clients in that case you don’t want that port 4000 inside the generated urls)

The question about the host is only needed if you use absolute urls instead of relative paths. (page_url vs page_path)

Hope this explains all your questions?

2 Likes

Hello! I want to run my app behind nginx, so I would like to run it on 127.0.0.1 ip, not to listen everywhere. So I tried hard last 2 hrs to solve this and have no success. :frowning: It is second time I fight this exact problem (last time in docker environment though)
I tried to add host: {127,0,0,1}, ip: {127, 0, 0, 1}

config :connectr, ConnectrWeb.Endpoint,
  http: [
    ip: {127, 0, 0, 1}, # host: {127, 0, 0, 1}
    port: String.to_integer(System.get_env("PORT") || "4000"),
    transport_options: [socket_opts: [:inet6]]
  ],
  secret_key_base: secret_key_base

I receive

** (Mix) Could not start application connectr: Connectr.Application.start(:normal, []) returned an error: shutdown: failed to sta│·
rt child: ConnectrWeb.Endpoint                                                                                                   │·
    ** (EXIT) shutdown: failed to start child: {:ranch_listener_sup, ConnectrWeb.Endpoint.HTTP}                                  │·
        ** (EXIT) shutdown: failed to start child: :ranch_acceptors_sup                                                          │·
            ** (EXIT) :badarg                                                                                                    │·
21:19:05.285 [info] Application connectr exited: Connectr.Application.start(:normal, []) returned an error: shutdown: failed to s│·
tart child: ConnectrWeb.Endpoint                                                                                                 │·
    ** (EXIT) shutdown: failed to start child: {:ranch_listener_sup, ConnectrWeb.Endpoint.HTTP}                                  │·
        ** (EXIT) shutdown: failed to start child: :ranch_acceptors_sup                                                          │·
            ** (EXIT) :badarg

I am tired, anybody, help me, please

Try removing :inet6 from the socket opts or provide the tuple representing ::1.

That’s a guess only though.