Dheeraj Bhaskar
Dheeraj Bhaskar

Reputation: 19039

how to show different content based on incoming domain?

Problem

I'm in over my head here, please point out if I'm trying to compare apples to bread.

I want to understand how people are doing this particular pattern (or set of patterns) which seems like magic to me.

Note: Concrete question below (answers need to be solutions to this)

Pattern

1. Galaxy meteor hosting

In the DNS config they ask us to set a CNAME from www.customer1.com (you) to galaxy-ingress.meteor.com.

This blows my mind, how are they able to redirect multiple sites based on source domain. Many of them might be high traffic. This should be performant as well.

2. Github.com Pages

Just add your domain in their settings and setup a CNAME to a constant domain they give you. Done.

Note: I'm hazy on the details - forward to constant domain or your GH pages user domain like user.github.io, don't recall precisely.

3. Gitlab.com

They give you an IP to point an A record to though, that doesn't seem very uptime friendly to me.

PS: I love these guys, Git + CI + docker repo for free, I must be dreaming.

4. Heroku

  1. Add domain via command line or via their web gui.
  2. Add a CNAME to your app-name.heroku

This (like a few above) would be the best, you get a default xyz.herokuapp.com URL you can use even without a custom domain.

5. surge.sh

  1. add domain to a file called CNAME (I was dubious, initially, this would work, it's just too simple :))
  2. add a CNAME to your xyz.surge.sh url

6. Modulus.io

(I can keep going with this list)

Concrete question

Setup that I'd like to have based on above

    • When www.website1.com has a CNAME to ingress.yourwebsite.com, show content related to their site
    • When www.website2.com has a CNAME to ingress.yourwebsite.com, show content related to their site
  1. The URL should show www.website1.com or www.wesbite2.com not ingress.yourwebsite.com
  2. Be easy to just add a new site programmatically
  3. Be performant and uptime friendly
  4. Implement on IaaS(Digital Ocean, AWS, etc) providers. (Even though as one answer suggests, you can use a PaaS(Heroku, Modulus, etc) provider's API, that's cheating isn't it, in the sense that one understands nothing by doing that as implementation is abstracted away with the API)

Performant: By this I mean that you're not doing this in an app layer if it could be done at the DNS layer.

Uptime friendly: By this I mean that if a server instance goes down, this service doesn't stop working

BONUS

How do I make this work for website1.com and website2.com (note no www.)?

As in www.website1.com forwards to website1.com (or the other way based on your preference)

I want to set this up internally like google apps does, I don't want the user to do a fancy setup on their DNS like CNAME at their root etc.

Technology preference

Please use one of these rather than their competitors if possible. Please mention when you're making a sub-optimal choice by doing this.

In order:

  1. MeteorJS
  2. NodeJS
  3. Javascript
  4. Cloudflare.com API
  5. Nginx
  6. Any github.com repo with high stars (say, 1k+)

PS: I'm mentioning this preference not be a dou*he but to re-use what I know already.

Possible solutions (which I'm not looking for):

Update #1 (13th July 2016)

What I've tried

    • Deployed a meteorJS app to heroku with a custom domain (say xyz.com) and tried routing a.xyz.com etc programmatically, got errors like herokuapp doesn't exist at this domain.
    • read a lot about hoerku's wildcard domain but didn't help
    • Deployed a meteorJS app to meteor.com with a custom domain (say xyz.com) and tried routing a.xyz.com etc programmatically, got errors like meteor app doesn't exist at this domain.
    • They gave no access to DNS (the place I thought this needed to work at)
    • meteor.com free hosting has been shut down
    • I'm guessing this should be easier than the tangled ball of yarn I'm making this out to be.
    • If I can programmatically setup CNAMEs (using cloudflare.com API, is this possible elsewhere?) like website1.yourwebsite.com then when someone hits website1.yourwebsite.com, I should know what content to serve based on URL (app level) then I can do a 301 redirect to actual host? The URL changes on 301 redirect. Dang!

Update #2 (30th July 2016)

    • updated question to clarify that this needs to be implemented on an IaaS (Digital Ocean, AWS, etc). If you're using a PaaS(Heroku, Modulus, etc) provider's API, you still don't know how this pattern has been implemented, it has been abstracted away with the API.

Upvotes: 2

Views: 232

Answers (1)

David Berger
David Berger

Reputation: 116

As an employee of Modulus I can provide some insight to how this works. Or at least how it works on the Modulus platform.

We use the incoming host header / SNI to know which project to route the traffic to. We have load balancers -> hosts -> servos. When a request comes in for your app it hits our load balancer which has a static IP address (more or less). Our load balancer does a host lookup in an in-memory database to find the location of your application. The load balancer routes the request to the host that the project is on, and then to the exact servo that the project resides on. A response comes from the app which goes back out of the servo to the host and then back to the load balancer which checks some things (like whether or not SSL is set for your project) before the response leaves the load balancer and goes back to the person accessing your app. When you look at project metrics on the modulus project dashboard, 'metrics' section, the 'response time' graph is showing how long it takes for this process to occur for a given route to your app.

When you put a custom domain into the mix this works pretty much the same. You set up your DNS to resolve your domain to our load balancer by using an 'A record.' You can also use a CNAME, but A records in my opinion work best. With an A record you define which load balancer all traffic is routed to first. This can affect things like x-forwarded-for. You can read more about using custom domains on our service here. We could go more in depth about this part, but it is explained well in that 'custom domains' article.

In regards to your question about programmatically setting up projects/apps it would be best to set up a separate project for each app/website. That would be easiest. You could create a single project which programmatically creates other projects with custom domains, but you would have to reverse engineer our CLI, or wait until we publish our public API (this should happen in a few months from now).

If you want to reverse engineer our CLI, you could do that by analyzing our open source here. You would have to create a token in the CLI by doing $ modulus token create first and then you can use that to make API requests to https://api.onmodulus.net/<XYZ or project etc>?create&authToken=<authToken goes here>

If you want to chat more, you can always find me in the Meteor Chef Slack group, which you can join here.

I hope this basic information can give you some direction in how you will solve this problem. :)

Upvotes: 1

Related Questions