Master_proxy running multiple sites: :ets.lookup(MyApp.Endpoint, :secret_key_base)

I am trying to build a single phoenix app (:my_app) that supports multiple sites (site1, site2, et.c). For this I have chosen the master_proxy package. The trick it does is the endpoint module becomes changed depending on the domain requested. I tried this with umbrella app, and it worked, but I did not like having multiple phoenix applications – I think it is better to run one phoenix app so I can share modules and not have conflicts with dependencies.

So I have something like this in my conf:

config :master_proxy,
       http: [port: 80],
       backends: [
         %{
           host: ~r{^site1\.com$},
           phoenix_endpoint: Site1.Endpoint
         },
         %{
           host: ~r{^site2\.com$},
           phoenix_endpoint: Site2.Endpoint
         }
       ]

also I make created configuration for the endpoint module:

config :my_app, Site1.Endpoint,
       url: [host: "site1.com"],
       secret_key_base: "xxx",
       render_errors: [view: Site1.ErrorView, accepts: ~w(html json), layout: false],
       pubsub_server: Site1.PubSub,
       live_view: [signing_salt: "xxx"]

For each site I have a separate Endpoint module and separate routes and separate static assets. I also add domains to /etc/hosts like this:

127.0.0.1  site1.com
127.0.0.1  site2.com

But when I start phx.server and make request to site1.com, I get an error:

[error] #PID<0.617.0> running WastePack.Endpoint (connection #PID<0.616.0>, stream id 1) terminated
Server: site1.com:80 (http)
Request: GET /
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        (stdlib 3.13) :ets.lookup(Site1.Endpoint, :secret_key_base)
        (web 0.1.0) lib/phoenix/endpoint.ex:474: Site1.Endpoint.config/2
        (elixir 1.10.3) lib/map.ex:798: Map.update!/3

What is this ets error? Maybe umbrella app is a better way to do this? Thank you!

When I see that ETS error, it’s usually a sign I’m trying to access a property of the endpoint before it’s booted. Can you post your main Application file?

I’m not sure what you mean - the whole umbrella can be deployed together (so it’s still “one app”) and Mix dependencies are resolved for the whole umbrella so there can’t be conflicts.

An umbrella app would let you organize this as two directories in apps, each with a standard “one router, one asset pipeline” setup.

with dependencies, each app in the umbrella has a mix.exs so I worry that if this was a umbrella app, then the apps for site1 and site2 might list conflicting dependencies. So previously I tried doing apps/site1/ as phoenix app and apps/site2/ as phoenix app all under the umbrella, and that worked. Maybe that is a better way? I was worried about too much repeating code.

my application.ex file is I think unchanged since installation:

defmodule Web.Application do
  # See https://hexdocs.pm/elixir/Application.html
  # for more information on OTP Applications
  @moduledoc false

  use Application

  def start(_type, _args) do
    children = [
      # Start the Telemetry supervisor
      Web.Telemetry,
      # Start the Endpoint (http/https)
      Web.Endpoint,
      # Start a worker by calling: Web.Worker.start_link(arg)
      # {Web.Worker, arg}
      {Phoenix.PubSub, [name: Web.PubSub, adapter: Phoenix.PubSub.PG2]},
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: Web.Supervisor]
    Supervisor.start_link(children, opts)
  end

  # Tell Phoenix to update the endpoint configuration
  # whenever the application is updated.
  def config_change(changed, _new, removed) do
    Web.Endpoint.config_change(changed, removed)
    :ok
  end
end

it is still in umbrella – the Web app is like the default endpoint and I was trying to add different endpoints inside of it. I hope I have explained clearly. Thanks!