Can we have multi-level subdomain in Rails like this?
sub1.sub2.mysite.com
Yes, you can check the subdomain the app is accessed from using request.subdomains
But if you are going to do something more advanced you should probably use
subdomain-fu
I don't see any reason why you couldn't have a subdomain of a subdomain being used in a rails app.
You'll want to setup a wildcard A record in your domain DNS and configure your http server to accept wildcard server aliases.
Then in your application_controller you'll probably want a before_filter that does some juju with
request.host
to do whatever you want, be it
Account.find_by_domain(parsed_request_host) or whatever.
Related
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.
I'm looking to set up custom domains for users. Much like Tumblr does.
I understand that the user must point their A record to an IP address. I found some information here: Custom domains in a Rails App
Can someone give me an example of this with a Heroku/Rails 3 setup? Is it even possible?
If you setup a wildcard DNS to point to your main app, you can use the :subdomain in config/routes.rb to handle your business logic.
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.
How do I redirect http://vinderhimlen.dk to http://www.vinderhimlen.dk ?
Your best bet would be to set up redirect with your DNS provider, so it happens long before any request reaches your server. From the Heroku Dev Center:
Subdomain redirection results in a 301 permanent redirect to the specified subdomain for all requests to the naked domain so all current and future requests are properly routed and the full www hostname is displayed in the user’s location field.
DNSimple provides a convenient URL redirect seen here redirecting from
the heroku-sslendpoint.com naked domain to the
www.heroku-sslendpoint.com subdomain.
For proper configuration on Heroku the www subdomain should then be a
CNAME record reference to yourappname.herokuapp.com.
It's not just DNSimple that does this. My DNS provider is 123 Reg and they support it but call it web forwarding.
I would recommend to do that much earlier in the request-lifecycle. If you would use Apache, you would add the URL Rewrite to the VirtualHosts file. On Heroku you need to add some Rack middleware.
Here as an example of the other way round (i.e. www.example.org -> example.org). I don't think you will have big problems of changing it to your usecase.
This way the requests won't show up in your log and don't need all of Rails' request parsing.
My solution:
Terminal:
heroku addons:add custom_domains:basic
heroku domains:add www.vinderhimlen.dk
heroku domains:add vinderhimlen.dk
And then (http://devcenter.heroku.com/articles/custom-domains):
class ApplicationController
before_filter :ensure_domain
APP_DOMAIN = 'www.vinderhimlen.dk'
def ensure_domain
if request.env['HTTP_HOST'] != APP_DOMAIN
# HTTP 301 is a "permanent" redirect
redirect_to "http://#{APP_DOMAIN}", :status => 301
end
end
end
Assuming you are using an action controller, just use redirect_to:
redirect_to "http://www.vinderhimlen.dk"
You should add the www domain as well.
heroku domains:add www.vinderhimlen.dk
Normally you'd do this at the HTTP server level using something like Apache's mod_rewrite module so that it occurs before the request even reaches the Rails' stack. However, Heroku don't give you access to their HTTP server configuration, so an alternative is needed.
I'd recommend taking a look at Refraction, which is Rack middleware designed to replace mod_rewrite. It lets you write your rewrite rules using good old readable Ruby code and it's still faster than using Rails itself for the task.
See Justice's answer in this SO article - his method for this is clear, simple, effective, and customizable.
I looked at subdomain-fu and it looks pretty easy to route all non-www and non-'' subdomain requests to a single controller.
But I also, need to send all external domains that are CNAME'd to my domain to the same controller. I have done a lot of searching and I can't find anything.
Summarized, if it is a subdomain on my domain it goes to Catchall controller, if it is any other domain than my domain, it goes to the same Catchall controller.
I am going nuts on this, any help would be appreciated.
You should check out the request_routing plugin. It allows you to easily route request by: subdomain, domain, method, port, remote_ip, content_type, protocol, etc.