Multiple domains on a single Phoenix app

I want to serve multiple domains in a single Phoenix app.
After Googling I landed on this:

Which recommends setting

config :my_app, MyAppWeb.Endpoint,
  url: [host: nil]

however the docs here:
https://hexdocs.pm/phoenix/1.5.3/Phoenix.Endpoint.html#module-runtime-configuration
don’t mention that.

I opened a bug here: Missing docs for Endpoint url: [host: nil] behaviour · Issue #3907 · phoenixframework/phoenix · GitHub
which revealed that, the behavior is not intentional, and should not be relied on.

My questions are now:

  • How do I enable multiple domains?
  • Can I just point my DNS to my server, and then most things work? Except for url generation in emails etc? When and where do I fall off the map?
7 Likes

Can I just point my DNS to my server, and then most things work?

No:
Websockets/LiveView seems to not be working out of the box. I end up in an infinite reconnect loop.

My logs helpfully tells me that:

Origin of the request: https://mydomain.com 
 
This happens when you are attempting a socket connection to 
a different host than the one configured in your config/ 
files. For example, in development the host is configured 
to "localhost" but you may be trying to access it from 
"127.0.0.1". To fix this issue, you may either: 
 
  1. update [url: [host: ...]] to your actual host in the 
     config file for your current environment (recommended) 
 
  2. pass the :check_origin option when configuring your 
     endpoint or when configuring the transport in your 
     UserSocket module, explicitly outlining which origins 
     are allowed: 
 
        check_origin: ["https://example.com", 
                       "//another.com:888", "//other.com"]

The first option won’t work since I have multiple domains. The second is viable.

The same is needed for :force_ssl as well.

Hey Kai,

Thanks for helping out, yet again :slight_smile:

I think my concern is that it’s abuse of a bug, and

The whole behaviour may change at any time.

according to this comment by Jose.

So what I’m asking is if there is a robust way of doing it, which is the “officially” recommended way.

For :force_ssl it’s documented. For :url it should work automatically for any domain if you use a conn as the first param for the url generating helpers. What you set as setting on the endpoint is just the default to fall back for other inputs to those helpers, which don’t have access to a current request.

1 Like

Thanks for clarifying! I was unsure of if :url in the endpoint was used for some sort of validation/security.

I deployed now, and everything seems to be working after I have deployed a test with:

config :my_app, MyAppWeb.Endpoint,
  url: [host: "mydomain1.com"],
  force_ssl: [host: nil],
  check_origin: [
    "https://mydomain1.com",
    "https://mydomain2.com"
  ]
4 Likes