Rails tenanted app with CloudFlare and subdomains - ruby-on-rails

I'm building a tenanted Rails application on Heroku which uses subdomains for each tenanted instance. The problem is I can't seem to get CloudFlare to properly cache a subdomain.
I have my Application hosted on heroku at say whatever.herokuapp.com
And using CloudFlare I'm pointing my main application at heroku's CNAME (whatever.herokuapp.com) and that works fine.
I'm using a wild cards *.mydomain.com on Heroku and then using CloudFlare again to point at them.
So say I create an app myinstance.mydomain.com on CloudFlare -> whatever.herokuapp.com
because I'm using the *.mydomain.com on Heroku it works fine.
BUT when I try to turn on the Acceleration (CloudFlare caching) it immediately breaks and all I see is a CloudFlare error Error 1001 telling me:
Most likely: if the owner just signed up for CloudFlare it can take a few minutes for the website's information to be distributed to our global network.

From their help desk:
Fundamentally in a standard set up the domain needs to be added to
CloudFlare in order for us to understand how to route traffic for that
domain.
If you wanted a setup where anybody in the world could CNAME to your
CloudFlare configuration, that is possible but it's an Enterprise
feature. We call it "Managed CNAME" - if that's something you're
interested in do let me know and I can put you in touch.
FYI, CloudFlare Enterprise averages at $5,000 a month.
CloudFlare is great in that it just works without much customization starting at zero cost, but unless your multi-tenanted app is for Bank of America or other Fortune 500 company I'd suggest something like Fastly ($5-50/month) or some other DIY caching solution that allows you to setup caching as you need rather than a one-size-fits-all top down solution.
https://devcenter.heroku.com/articles/fastly
Works directly with Heroku but there might be other solutions that work equally well.

That error can also occur if you're pointing a domain/subdomain not on CloudFlare to a domain that is on CloudFlare (creates a DNS resolution lookup error). I would probably contact CloudFlare support for additional assistance and troubleshooting.

Related

1&1 domain pointing to Heroku

I am aware that there have been a few discussions on this one but none have given a definitive answer. I am hoping this will help me and others.
Problem:
I have a domain name (www.xyz.com) registered with 1&1.
I want users to be able to type this in and be shown my website. A Heroku web app.
I want the domain name (www.xyz.com) to be displayed. Not any subdomain url or the heroku app URL.
I do not want the set-up do be anything that will have a detrimental impact on SEO.
Note: I have just got off the phone with 1&1 and they have said that my only options are to do a frame redirect or a http forward. Neither of these meet the above requirements.
Additionally, other posts have suggested finding out what the Heroku IP address is and using this but Heroku recommend against this as they might change it without notice.
Please could I ask that any one kind enough to respond spells things out a little. Anyone having problems with redirects is likely to be new to this.
Thanks.
never used the 1&1 services, but solving your problem is pretty straightforward.
Take the following steps:
Add you domain to heroku. heroku domains:add www.xyz.com . If you have more than 1 app in your heroku account, remember to pass the --app flag
Now you should have something like myherokuapp.herokuapp.com where myherokuapp is the name of your app on heroku
Go to 1&1 and create a CNAME record pointing to myherokuapp.herokuapp.com
I found this video to be helpful - https://www.youtube.com/watch?v=ZLVBBAnrrL4
Basically, as noted by #Kevin Lawrence above, you use the 'www' subdomain.
I've never used 1&1 but my DNS provider (dreamhost) does not allow CNAMEs on the main domain name either. It does however allow me to create a CNAME for the www subdomain which was good enough in my case.
I did this:
heroku domains:add www.mydomain.com
create a CNAME record pointing to mydomain.herokuapp.com
Have mydomain.com redirect to www.mydomain.com
It's not exactly what I wanted (or what you want) but it works.
What worked for me was to user Namecheap.com's FreeDNS service that provides free automatic redirect for your TLD and subdomains directly to Heroku, while keeping your domain visible:
example.com and www.example.com now point to exampleapp.herokuapp.com
I had to have a live chat with Namecheap's support to complete the domain verification process, but they answered really fast! Love to namecheap, 1and1 is really crappy, moving my domains away soon. :)
I got this to work properly! No need for CNAME at all. Create a A record in heroku like in this link - creating a custom room domain - provided by heroku (of course, change example.com to your root domain):
heroku domains:add example.com
Here, example.com is the ROOT domain. Once you get an A record, execute the following command
heroku domains:wait example.com
Now verify your domain has been provisioned:
heroku domains -a [your custom heroku app name]
And you get this:
=== [your custom app name] Custom Domains
Domain Name DNS Record Type DNS Target
example.com ALIAS or ANAME elliptical-blueberry-1euo3460fyrtc8zdgulv0f7o.herokudns.com
Next, get the IPv4 IP address of elliptical-blueberry-1euo3460fyrtc8zdgulv0f7o.herokudns.com I got it by using a lookup service.
Updating 1 and 1
Go to 1and1.
Click the DNS tab for your custom domain e.g. example.com
Delete the existing A record
Create a new A record and enter in the # symbol if it asks you, or else I think it is the default AND enter in the IPv4 address
For testing this out, make the TTL 1 min until it's stable
Give it time to propagate. Could be a few minutes to 24 hours.

1and1.com to Heroku

Edit: Just to be clear, actually I only want to use a different webserver, not mail server. It has to stay the same.
I've got a 1and1 plan including webspace and email service. As 1and1 doesn't support Ruby, I created my website at Heroku.
I'm now trying to point my www.example.de url to my example.herokuapp.com domain. As this is the very first time I'm doing this, please alert me if I'm missing something important.
The website uses the 1and1 mail server. I found out that, due to that fact, I can't go the cname way but need a A Record (or ANAME Record?). I already pointed heroku to the right urls and now need to set up 1and1 and a dns service.
I registered at dnsmadeeasy.com and created an ANAME Record:
Name: [left blank]
FQDN or IP: myapp.herokuapp.com
TTL: 1800 (I've got no idea what that is)
After creating that, dnsmadeeasy.com shows me several "System NS Records" which look like nameservers?
ns0.dnsmadeeasy.com
upto
ns4.dnsmadeeasy.com
As far as I understand I now have to enter the nameservers above at 1and1.
My question now is, does this disable the by default working mail server connection? If yes, how would I point back to it from dnsmadeeasy.com? Or is there a better way to do this?
It seems the easy way to do it now is with Point DNS. They have a free developer plan: https://devcenter.heroku.com/articles/pointdns
Enter the Point DNS servers into the 1and1 Domain Manager.
The problem was solved by just adding a A-record at 1and1 pointing at Heroku. No nameservers or any extra service needed.
Here is a more detailed update:
First you have to go to the Heroku app settings. There you can add domains for your app, like www.mydomain.com.
Then you use a service to get the IP address of the server where your Heroku app instance is running. (Just get the IP address of your instance of yourapp#herokuapp.com.) Then you add this IP address as a A-record to the 1and1 app settings. Now you have to wait for the settings to propagate over the DNS servers.
Basically you point your 1and1 app to the server on which your Heroku app runs and inform your Heroku app that there probably is some app trying to reach through to it, which has a specific address, like www.mydomain.com. That's how they find each other.

need a crash course in HTTPS / SSL for Rails

I've got our Ruby on Rails app up and running on Heroku using HTTP. Now it's time to use HTTPS during the login process and for all transactions after the user is logged in. But I'm not sure where to start.
configuration
We're using:
Ruby (1.9.2)
Rails (3.0.5)
Devise (1.5.3)
Our domain (registered by GoDaddy) is oursite.com (not its real name), which resolves to oursite.herokuapp.com. I want secure transactions to be performed in a subdomain https://secure.oursite.com. I've purchased an SSL certificate from GoDaddy, created the key files, signed up for the Zerigo DNS service and set oursite.com nameservers to point at Zergo's servers. And on Heroku, I've done:
heroku domains:add secure.oursite.com
heroku ssl:add final.crt site.key
heroku addons:add ssl:hostname
the questions
If a user arrives at our site under http://oursite.com, how (and when) do I switch to https://secure.oursite.com?
How do I enforce using https for any secure transaction (e.g. submitting a password)?
How does one test this stuff using localhost:3000?
Concrete answers, general answers, and pointers to tutorials and examples are equally welcome. Thanks!
First:
redirecting from http://example.com to https://example.mysite.com
... is a very specific question that supersedes this very general question. I'll summarize the best bits of info I found in the last 24 hours, as it may be helpful to someone else.
The Heroku article on SSL is a must-read if you're deploying on Heroku.
Heroku also has an article describing how to purchase an SSL certificate from a general vendor as well an article describing how to purchase an SSL certificate from GoDaddy.
I was stuck for a while trying to configure the CNAME records for my Zerigo DNS service. The punch line is that if you create your Zerigo account using the Heroku dashboard, then you must configure your CNAME records using the Heroku dashboard as well. Gory details listed here.
If you're planning on upgrading to Rails 3.1, this is a good time to do so, since it has a built-in force_ssl method that is a clean replacement for various add-in gems (notably ssl_requirement).
Having said as much, the implementation of ssl_requirement in https://github.com/rails/ssl_requirement/blob/master/lib/ssl_requirement.rb is worth looking at, just to see how it uses redirect_to and the request object.
Simone Carletti has a comprehensive blog entry Configuring Rails 3 to use HTTPS and SSL, covering both Rails 3.0 and Rails 3.1.
Hope this is helpful...
I would have a look at ssl_requirement. This allows you to secure various parts of your application thus forcing you to only serve certain pages over HTTPS.
https://github.com/rails/ssl_requirement
With local development, you'll need to setup some sort of Apache / NGinx setup with a locally signed cert bolted on. A quick google uncovered this:
http://www.subelsky.com/2007/11/testing-rails-ssl-requirements-on-your.html

Rails, Heroku and Subdomains. Is my special case scenario feasible?

Here is my scenario:
I have an application that will have to support multiple clients. Each client will be given a subdomain for there service. We will also have a brochure website that doesn't have the application, its just a website about the product and how potential clients can setup an account with us.
Given:
www.mycoolsite.com would point to a brochure app on Heroku.
client1.mycoolsite.com, client2.mycoolsite.com and client3.mycoolsite.com would all point to the same SaaS application that could tell the difference between each request and I should be able to handle so they only see their date (i.e. setting a global client_id or something like that)
How do I go about doing this? I haven't done a lot with DNS so I'm pretty clueless about where to start with this.
Thanks.
No sweat. We do that now, at Heroku. We happen to use Godaddy for the domain registrar, but any DNS control panel will let you do the same thing.
The other explanations I read here are a little general, here are the specifics...
The explanation at heroku is very good, at : http://docs.heroku.com/custom-domains
(there's even a very good screencast shows step by step)
the key thing is if your ROOT domain (mycoolsite.com) is at Heroku you want to create THREE "A" records, because they do some fault-tolerant crossover magic. So you'd have an A record for
75.101.163.44
75.101.145.87
174.129.212.2
Now for each subdomain you create a CNAME record
www -> proxy.heroku.com
client1 -> proxy.heroku.com
client2 -> proxy.heroku.com
client3 -> proxy.heroku.com
NOW on the HEROKu side, you have two apps right? The 'brochure app' and the saas app.
Login, and for each app go to Resources -> Addon -> Get More Addons ->Custom Domains (free)
for the brochure app, add ONE domain: www.mycoolsite.com
for the saas app, add each of the clients, eg:
client1.mycoolsite.com
client2.mycoolsite.com
client3.mycoolsite.com
That's it. works like a champ. Have fun.
What you're trying to do is very feasible, and quite easy to do.
You're going to need a combination of A and CNAME records. Simply put, A records map host names to IP addresses, and CNAME records act as aliases for A records.
Let's assume that your SaaS app is hosted at 10.0.0.1 and your Heroku app is at 192.168.0.1, and that you want www.mycoolsite.com and mycoolsite.com to point at the same IP.
(Note: I've never hosted anything at Heroku, so configuring DNS that may be slightly different)
First thing you'll need is an A record for the domain itself. (I've used BIND Zone File Syntax here - hopefully your DNS provider has a much simpler administration system.)
mycoolsite.com. A 192.168.0.1 ; heroku
www CNAME mycoolsite.com ; also heroku
These two records tell us that mycoolsite.com should point at Heroku's IP address, and that www.mycoolsite.com is an alternate name for mycoolsite.com, which will also resolve to Heroku's IP address.
Now, let's set up the DNS for your SaaS site. You could set up an A record for each sub-domain, but if you move servers, you'll have a lot of IP addresses to update. The simplest option is to configure one A record, then point your app's sub-domains at it:
sassapp A 10.0.0.1 ; saas app server canonical name
client1 CNAME sassapp ; alias
client2 CNAME sassapp ; alias
client3 CNAME sassapp ; alias
You can then add as many CNAMEs as you need.
I don't see this being an issue. Rails has had support for subdomains like that in the past with help from gems like subdomain_fu. In Rails 3, subdomain support is actually built in and covered by Ryan Bates http://railscasts.com/episodes/221-subdomains-in-rails-3. Take a look at that screencast for a good direction of where to start.
I believe you'll need the custom domains add-on for Heroku http://docs.heroku.com/custom-domains.
This won't be a problem. For DNS set up an A record for mycoolsite.com pointing to the server where you want your application. Set up an A record for www.mycoolsite.com that is configured for heroku. Now you will also want to redirect traffic that comes in on mycoolsite.com without www and redirect to www.mycoolsite.com, this will keep your top-level domain serving up your brochure app. Once requests are getting to your application you can follow the tutorial that raidfive linked to that will help you through handling subdomains inside of your application.

Subdomains and locally installed Rails app

I can't figure out what I'm overlooking, perhaps it's obvious or lack of understanding.
The app I'm working with uses subdomains which on the hosting server work properly. I figured locally installing would kick up some issues around routing, so I read up on making changes to /etc/hosts and using the Ghost gem. Both seem to work fine i.e. localhost:3000/ becomes myapp.local:3000 but I don't understand how to go about logging into a subdomain account. Here's an example...
myapp.local:3000/session/new = the default login page for the app
myapp.local:3000/signup = default signup page
I can create an account here e.g. Sub1
The thank you page is shown w/ the reference to sub1.myapp.com which points to the hosted app (the local db shows this domain as well)
sub1.myapp.local manually added to /etc/hosts and dscacheutil -flushcache
sub1.myapp.local:3000/session/new is the subdomain
login attempts return that this isn't a valid domain. This seems to make sense because the local db shows the url as sub1.myapp.com on the hosting server.
So my question is whether there's a local workaround that I can use for development or have I totally missed a fundamental concept along the way?
you might just want to try putting the actual dot com in your /etc/hosts file.
ie:
127.0.0.1 sub1.myapp.com
127.0.0.1 myapp.com
127.0.0.1 anyothersubdomains.myapp.com
what this usually does is trick your computer into thinking it is the host of all of those, so you can't go to the real site anymore in a web browser.
if you do want it to be .local, presumably so that you can refer to the real online site while working on a local copy, you should probably take a look in app/controllers/application_controller.rb (sometimes application.rb) and look for logic in there that helps determine what to do depending on the subdomain. maybe its hard coded to only look for a .com or something.
If you are using the webrick server or something like Puma for development you can use lvh.me to access your subdomains. e.g.
http://sub.lvh.me:3000/
http://lvh.me:3000/ is equal http://localhost:3000/

Resources