You’re reading Signal vs. Noise, a publication about the web by 37signals since 1999.

37signals

How to do Basecamp-style subdomains in Rails

David
David wrote this on Jan 08 2009 / 32 comments

David wrote this on Jan 08 2009 There are 32 comments.

Luisgo 08 Jan 09

Thank you.

Marten Veldthuis 08 Jan 09

The modern way for step 4 would probably be by using default_scope, right?

Adam 08 Jan 09

Sweet Thanks,

Can you make it a bit simpler next time? :o)

srboisvert 08 Jan 09

Just a wee blog usability heads-up. Browsing with JavaScript disabled (the way I roll) nothing at all shows up for this post – not even an indicator that something isn’t showing up.

You also might want to check your error message on a JavaScript disabled form submit.

I’ll be bookmarking the code though so thanks. This is definitely something I will need.

DHH 08 Jan 09

Marten, I wouldn’t use default_scope for this. Anchoring off the current account makes it explicit that there’s a security scope in place. I like better to follow the path of execution like this.

IMO , default scope should only be used for things like a natural order, like “updated_at DESC ”.

Also added a noscript block with just a link to the code example.

Rodrigo 08 Jan 09

Hi David,

I was thinking about that just yesterday at night and was planning to try differente approaches.

Thank you!!!

Thomas R. Koll 08 Jan 09

Didn’t Rails move from @params to params? Cuz I usually don’t use such before_filters anymore for e.g. current_user and current_account.

just a thought…

Anonymous Coward 08 Jan 09

Why on earth would anyone browse with JavaScript disabled? In 2009?

DHH 08 Jan 09

Thomas, we did, so you could have the entire instance variable space to yourself. Using that space for @current_account is exactly as it was intended.

Anonymous Coward 08 Jan 09

No more account_location?

Great stuff. Thanks!

Jon Crawford 08 Jan 09

In my opinion, you should use the last subdomain, “request.subdomains.last” instead of the first. For our online stores at Storenvy, I’ve seen a lot of users try “www.subdomain.storenvy.com”. I’ve even seen store owners publish their links in that format. So, I figured I should just make it work for people.

I forked the Gist and added my slight alteration. http://gist.github.com/44415

Any reason why one shouldn’t do this? I noticed Basecamp redirects if you put “www” at the start of the URL . But is that necessarily better?

DHH 08 Jan 09

Jon, I think it’s better to have one authoritative URL , so yes, I think it’s better to do the redirect, but if you don’t do that, then last could work too.

Duarte 08 Jan 09

Thanks for posting this!

Brad 08 Jan 09

Does anybody know how to get subdomain.localhost working for running in a local dev environment?

DHH 08 Jan 09

Edit your hosts file. On OS X , it’s in /etc/hosts. I have:

127.0.0.1 david.basecamp.i

Then I access http://david.basecamp.i:3000/ after I start the server with script/server.

Andy 08 Jan 09

You don’t need to bother with the ServerName *.domain.tld, apache doesn’t seem to support wildcards there, and it doesn’t matter anyway since if you’re only running one virtual host, or your wildcard domain is the first vhost loaded by apache, everything that doesn’t match another vhost will be directed to there. ServerAlias seems to support wildcards though. I’ve never needed to change the apache configuration if all the requests come into one vhost, even with NameVirtualHosts configured and enabled.

DHH 08 Jan 09

Andy, you’re right. It’s supposed to go in the ServerAlias. I’ll update the code. You can well have multiple applications on the same web server that all respond to this, though.

Anonymous Coward 09 Jan 09

I use lynx to view my infanets. That’s the way I roll, son.

N/A 09 Jan 09

This page seems to have some javascript at the bottom that calls: http://twitter.com/statuses/user_timeline/37signals.json?callback=twitterCallback2&count=3

Whenever I load this page, I get the grey htauth login box saying: To view this page you need to log in to area “Twitter API ” on twitter.com:80

I click cancel and the 37Signals page logs

Andy 09 Jan 09

“You can well have multiple applications on the same web server that all respond to this, though.”

I don’t know what that means. Maybe you can put:

NamedVirtualHost *:80
<virtualhost *:80>
ServerName www1.example.com
ServerAlias *.example.com
DocumentRoot /srv/1
</virtualhost>

<virtualhost *:80>
ServerName www2.example.com
ServerAlias *.example.com
DocumentRoot /srv/2
</virtualhost>

but (if apache doesn’t complain about this and still runs), all requests for blah.example.com will go to which ever vhost matches the ServerAliases first, /srv/1 in this case.

You need to have unique values in each ServerName and ServerAlias for each vhost, even if they are wildcards and match multiple names.

ServerName is also used to specifiy the canonical name for the server/vhost instance. Also make sure you have UseCanonicalName Off so links and names that apache might generate (like for error pages, if you aren’t sending those through your app code also) match the host header rather than the ServerName value.

This is actually why I usually set up the initial vhost to be some generic server that contains no files (or a redirect somewhere else) and create specific vhosts for each other domain that this server serves. This way, if something gets confused (say the case of an HTTP /1.0 client which doesn’t send a Host header) a request for second-vhost.example.com that ends up on first-vhost.example.com doesn’t show the content for the wrong domain. This is more of an issue with shared virtual hosting though.

DHH 09 Jan 09

Andy, I was talking about running multiple apps from the same Apache instance. Imagine Basecamp running on example1.com and Backpack running on example2.com:

<virtualhost *:80>
ServerName www.example.com
ServerAlias *.example1.com
DocumentRoot /srv/1
</virtualhost>

<virtualhost *:80>
ServerName www.example2.com
ServerAlias *.example2.com
DocumentRoot /srv/2
</virtualhost>

Ric 09 Jan 09

Thanks for publishing this info, David. These sorts of svn articles (i.e. insights into how 37signals apps use rails) are great.

Erik Dungan 10 Jan 09

So, in this example, would the basecamp home page and info pages be served with a separate VirtualHost that only responds to www.example.com?

DHH 10 Jan 09

Erik, exactly.

rohandey 10 Jan 09

Please keep pouring more snippets like these…..really helpful… thankyou

SuatE 10 Jan 09

Please keep pouring more snippets like these…..really helpful… thankyou

Robby Russell 11 Jan 09

David & all,

I decided to take this example a step further and provide a tutorial that allows you to handle scoping on accounts through subdomains and also handling a www site.

You can check out, Subdomain accounts with Ruby on Rails explained on my blog.

Alex 12 Jan 09

David, do you maintain a list in the app of subdomains that are not allowed (e.g. www, admin, support, blog, help)? Or create dummy accounts with those names?

rubp 13 Jan 09

wandering – In know that in some apps 37s support https - how the redirection works ? 10x.

Ben 14 Jan 09

Alex’s question is a good one—which subdomains should be reserved?

Has anyone thought through this and created a list of subdomains a typical web app/company would want to reserve?

Does 37signals reserve Basecamp subdomains for purposes other than user accounts?

Robby Russell 14 Jan 09

Alex/Ben,

My post here shows you how to reserve subdomains from being used by your customers.

View post here

Alex 14 Jan 09

Cheers Robby

This discussion is closed.

David

About David

Creator of Ruby on Rails, partner at 37signals, best-selling author, public speaker, race-car driver, hobbyist photographer, and family man.

Read all of David’s posts, and follow David on Twitter.
If you liked this post by David, you’ll probably like reading The best lawyer experience, Link: Searching for the 37th signal: Rails Programmer, and Play this!

From 37signals

We make the world’s #1 Project Management App

We’re the team behind Basecamp. Since 2004, Basecamp has been the best way for millions of people to collaborate on projects together. Try it yourself.

REMOTE: Office Not Required

Our newest book that shows both employers and employees can work together remotely, from any place, anytime, anywhere. Coming fall 2013.

    Explore 13 years of Signal vs. Noise

  • Business
  • Design
  • Programming
  • Support
  • Sysadmin
  • Writing
  • Best of
  • Everything

New here? Start with our best hits:

  • Forget the resume, kill on the cover letter
  • How to get good at making money
  • Forget passion, focus on process
  • Give it five minutes
  • It just doesn’t matter
  • … all of “The Best of Signal vs. Noise”

Back again? Catch up on our latest posts:

  • The Starter League launches Starter School
  • Building Know Your Company
  • Video: Steve Jobs: The Most Important Thing (via…
  • Insight: The first exception should be the hardest…
  • Apple: The organizational Rorschach
  • … all posts on Signal vs. Noise

Find more opportunities on the 37signals Job Board.
Ads via the Deck

Like what you’re reading?

Join the 123,000+ others and subscribe to our RSS Feed 

Want to learn how to design, code, and ship web apps with Ruby on Rails? Join The Starter League.

Meet the writers of Signal vs. Noise. Follow 37signals on Twitter. Subscribe to our Newsletter and RSS.

Content copyright ©1999-2013 37signals, LLC.