Loading the endpoint configuration from the system environment

I have the following endpoint initialization in lib/weather_web/endpoint.ex :

defmodule WeatherWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :weather

  socket("/socket", WeatherWeb.UserSocket)

  # Serve at "/" the static files from "priv/static" directory.
  #
  # You should set gzip to true if you are running phoenix.digest
  # when deploying your static files in production.
  plug(
    Plug.Static,
    at: "/",
    from: :weather,
    gzip: false,
    only: ~w(css fonts images js favicon.ico robots.txt)
  )

  # Code reloading can be explicitly enabled under the
  # :code_reloader configuration of your endpoint.
  if code_reloading? do
    plug(Phoenix.CodeReloader)
  end

  plug(Plug.RequestId)
  plug(Plug.Logger)

  plug(
    Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json],
    pass: ["*/*"],
    json_decoder: Poison
  )

  plug(Plug.MethodOverride)
  plug(Plug.Head)

  # The session will be stored in the cookie and signed,
  # this means its contents can be read but not tampered with.
  # Set :encryption_salt if you would also like to encrypt it.
  plug(
    Plug.Session,
    store: :cookie,
    key: "_weather_key",
    signing_salt: "1iiZbK3y"
  )

  plug(CORSPlug)

  plug(WeatherWeb.Router)

  @doc """
  Callback invoked for dynamically configuring the endpoint.

  It receives the endpoint configuration and checks if
  configuration should be loaded from the system environment.
  """
  def init(_key, config) do
    if config[:load_from_system_env] do
      port = System.get_env("PORT") || raise "expected the PORT environment variable to be set"
      {:ok, Keyword.put(config, :http, [:inet6, port: port])}
    else
      {:ok, config}
    end
  end
end

However when running I get this error.

** (Mix) Could not start application weather: Weather.Application.start(:normal, []) returned an error: shutdown: failed to start child: WeatherWeb.Endpoint
    ** (EXIT) shutdown: failed to start child: Phoenix.Endpoint.Handler
        ** (EXIT) an exception was raised:
            ** (RuntimeError) server can't start because :port in config is nil, please use a valid port number
                (phoenix 1.3.4) lib/phoenix/endpoint/handler.ex:55: Phoenix.Endpoint.Handler.to_port/1
                (phoenix 1.3.4) lib/phoenix/endpoint/handler.ex:47: Phoenix.Endpoint.Handler.default/3
                (phoenix 1.3.4) lib/phoenix/endpoint/handler.ex:33: anonymous fn/5 in Phoenix.Endpoint.Handler.init/1
                (elixir 1.12.0) lib/enum.ex:2356: Enum."-reduce/3-lists^foldl/2-0-"/3
                (phoenix 1.3.4) lib/phoenix/endpoint/handler.ex:31: Phoenix.Endpoint.Handler.init/1
                (stdlib 3.14.2) supervisor.erl:301: :supervisor.init/1
                (stdlib 3.14.2) gen_server.erl:417: :gen_server.init_it/2
                (stdlib 3.14.2) gen_server.erl:385: :gen_server.init_it/6
                (stdlib 3.14.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

And idea?

Show us your config/dev.exs but by the looks of it, you need to specify a port on which your app will listen after you start it locally.

Example config:

config :your_app, YourAppWeb.Endpoint,
  http: [port: System.get_env("PORT") || 4000], # <-- YOU ARE INTERESTED IN THIS HERE
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [],
  allowed_cors_profile: "all"
2 Likes

here :slight_smile:

use Mix.Config

config :weather, WeatherWeb.Endpoint,
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: []

# Do not include metadata nor timestamps in development logs
config :logger, :console, format: "[$level] $message\n"

# Set a higher stacktrace during development.
config :phoenix, :stacktrace_depth, 20

Add the line I pointed you at and try again, it should work (or blow up with a different error :003:).

4 Likes

tnx so so much great developer :slight_smile:

Happy to help!

1 Like