One domain, two rails apps on Heroku - ruby-on-rails

I am building a multi-tenant Rails 5 app (will be hosted at heroku) at the moment (using apartment gem) which will have clients scoped by subdomain, e.g. client1.example.com, client2.example.com, client3.example.com. All seems pretty straight forward, but I would love to have a second Rails app for the rest of the site e.g. example.com/pricing, example.com/faq. What would be the best solution to achieve this design:
example.com/pricing - served by Rails App 1
example.com/faq - served by Rails App 1
example.com/{sign_in | sign_up} - served by Rails App 2
clientX.example.com/{projects | profiles | other stuff} - served by Rails App 2
I have a suspicion that sign in/up bit might not be possible due to same URL structure, so I might need to have an extra logic built it for it maybe under app.example.com/sign_up or even under Rails App 1. Any suggestion how to build this in a better way would be appreciated!

A little concerned this will be closed with "overly broad", but a simple solution here is to do heroku domains:add www.example.com and heroku domains:add example.com to Rails app 1. Then heroku domains:add *.example.com on Rails app 2 and to have two entirely separate apps on Heroku.

Don't think you can mount two apps under the root directory. You might be able to achieve this if you're willing to namespace your Devise paths under a subdirectory, eg. /session/sign_up and /session/sign_in
This will require an extra app (App 3) which just runs Devise loaded and deployed under the /sessions subdirectory. You'll need to configure the relative url root for this app.
This will make authentication more complex as your session authentication cookie will be under your root domain instead of your individual subdomains. You'll probably need to use the domain: :all or domain: .<domain>.com option in initializers/session_store.rb to share the cookie with subdomains. secret_key_base also needs to be identical across all your apps.
You'll also need to play with Devise's session creation to redirect to the correct subdomain for the user upon signing in. Fun fact to think about - what if the user has accounts on multiple subdomains with the same email? Devise/Warden scopes might offer a way to handle that.
On the Heroku side:
Heroku can only route requests for one domain to one app (App 1). The Rack reverse proxy posted above will allow you to route authentication requests to App 3. For individual subdomain requests to be routed to App 2, you'll need to add each subdomain to App 2 as a separate custom domain.

Related

Using rails app as on extension of an existing website

I am trying to use rails app as an extension of my Weebly app.
current domain is hosted by Weebly. I am trying to the following,
I am trying to use the one domain for two different applications(Weebly template website and Rails application)
I thought of two solutions and I don't know if any of them are applicable.
solution
add a subdomain eg. welcomerailsapp.example.com
or
www.example.com/welcomerailsapp
I will be pushing my Rails app to the Heroku server
little guidance would be appreciated
thank you
You can use a CNAME record to do what you want. This would be done at your domain registrar or DNS provider.
Example:
Domain: mydomain.com
CNAME www => yourweeblyhost.com (Weebly app server)
CNAME rails => yourrailsapp.com (Heroku server)
www.mydomain.com would then route to your Weebly app, rails.mydomain.com would route to your Rails app.
This can be done on Weebly via the settings tab under your domain. So all you'd need to do is pick a name for your subdomain, with that as the "name" for the CNAME record and point it to the URL Heroku gives you for your Rails app.
You can also get more complex with it by using wildcards.
So if you only wanted one subdomain (www), for example, to route to the Weebly app; you can configure it as such by creating a CNAME for the www subdomain and pointing it to Weebly as noted above. Then, by using a wildcard (usually * on most providers) as the "name" you can tell the internet that [anyotherthing].mydomain.com should route to the Rails app without having to define each subdomain manually.

How do I set up a Rails page as a subdomain of another site?

We're trying to create pages in our Rails app that will eventually live on a subdomain of another partnering site. This would be like StatusPage, which allows users to create a status page with their account on the StatusPage site and then attach it to their own subdomain (e.g. status.usersite.com).
For example, if we wanted one of our pages (www.oursite.com/users/bobsplumbing) to be a subdomain on another site (ourservice.bobsplumbing.com), how would we go about it?
If it's useful info, we use Heroku to host the Rails app and we also utilize Route 53 and Cloudflare.
From your example I understand that you want to have multiple web apps since that would be your customer domain and your page will redirect to that page.
You will be better off to do NGINX (or whatever you use) redirects since they are faster and will take less time, being cached by the browser after the initial load.
To answer your question you can add this code to your routes:
sites = %w(bobsplumbing catsandboots)
sites.each do |name|
match "users/#{name}" => redirect("https://ourservice.#{name}.com")
end
You can also have a look at apartment gem.

Ruby on Rails allowing sessions between ports locally

Basically I am developing an API in rails with RocketPants and Devise and I'm creating a client with AngularJS. since they are in folders maintained by seperate people I run the rails api on localhost:3000 and the client on localhost:8000 and in the live environment they will be on subdomains of the same top level domain. api.example.com app.example.com.
I have allowed for cross domain requests using Rack Cors and this seems to work fine, I can query for things and log in by sending my credentials to the API (I have also checked if this works by returning the logged in user's id).
However the client does not seem to hang on to the session, after I log in and get back confirmation that I logged in successfully and I make another request it says the current_user is Nil.
I have allowed for subdomains in rails I think by using the following in session_store.rb
AppName::Application.config.session_store :cookie_store, key: '_app-name_session', domain: :all
I cannot test this however.
Is there a good way to share sessions between ports locally? Or is there a good way to emulate subdomains for local testing between 2 projects (1 rails, 1 standalone)?
Have you considered using Pow to serve your apps in development?
You could then run them on the subdomains, just like you do in production.

Wildcard domains on heroku

How can I use wildcard domain on Heroku? My application is using subdomain.
I followed the Heroku custom domain article and mapped my *.mydomain.com to myapp.herokuapp.com. When I visit dev.mydomain.com it points to heroku app but on Heroku app I cant find the subdomain.
In short I want to use subdomain on heroku, like dev.myapp.herokuapp.com. Any suggestions?
The wildcard setup on Heroku instructs Heroku to point any request for a subdomain of given domain to your application.
But here stops Heroku responsibility. Then your application must be able to handle such requests at application level.
In Rails, you can inspect the request details with the request object in your controller. And you can access the specific subdomain with request.subdomain.
So, for example, if you added *.example.com and someone access foo.example.com, the request object will respond with the following values:
request.host
# => foo.example.com
request.subdomain
# => foo
Now it's your responsibility to use such information in your app according to what you are trying to achieve.

Multiple domains pointing to single Heroku Rails app via nameservers displaying different content?

We have a Rails 3 app which allows users to create a profile and access it with a subdomain. So for example:
user1.app.com
user2.app.com
user3.app.com
Now, suppose they wanted to point their own domain name to their profile, so www.user1.com shows user1.app.com, and www.user1.com/my-content/ shows user1.app.com/my-content/. Is it possible for them to simply change their nameservers to point to us, and we handle the routing? I'm afraid it would be a deal breaker if the user had to do any DNS configuration beyond just changing their nameservers.
Thanks!
This is really two questions.
So I guess I'll answer it like that.
How can I allow customers to add a custom domain to my heroku-based app?
So, in your example, their domain name is www.user1.com
Two things need to happen
www.user1.com needs to be added to your heroku domains for the app
the dns for www.user1.com needs to be set to the heroku servers
In order to add this new domain, I guess you need to store the custom domain in the app,
and when it is changed, or created, ensure a queued task is setup to push this config change to heroku.
In order to do the dns correctly, I hope it is enough that they add a CNAME for user1.app.com.
Therefore, if you have a wildcard CNAME linking to heroku's dns, you can avoid the type of downtime that can occur if Heroku gets DOS-ed again.
How can I show content based on domain, rather than just subdomain?
Well, somehow you already differentiate user1.app.com from user2.app.com
Maybe you just sniffed request.host.
Now you just have to try the custom domain first.
Maybe this'll work.
before_filter :set_client
def set_client
#client = Client.find_by_custom_domain(request.host) || Client.find_by_subdomain(request.host.split(".").first)
unless #client
raise "unrecognised domain #{request.host}"
end
end
You need to get them first of all have them set www.user1.com to point to proxy.heroku.com (or setup your own cname entry to proxy.heroku.com and get them to cname their domains to that) and then you need to register their custom domain with your heroku app so the correct application responds at Heroku stored against their account?? in your application so it can be matched on incoming requests.
This technique is employed in the Locomotive Rails CMS so I'd suggest looking at that - it uses the Heroku gem INSIDE the application so custom domains can be added via the site administrator which in turn talks to the Heroku API to add the custom domain to the application.

Resources