Creating multiple sites on the same domain without using symlinks with Apache
We were searching for a way to support multi-site installations (subsites) on the same domain, that is, to have:
www.example.com/
www.example.com/sitea
www.example.com/siteb
www.example.com/sitec
etc.
with different content/themes/modules etc. but on the same Drupal 5.x installation. The normal way to do this is to create the appropriate
/sites/www.example.com.sitea/settings.php
etc...
files and then to create recursive symlinks for each subsite, eg.
ln -s drupal/. drupal/sitea
etc..
The problem with this approach is that for multiple sites, it permits for recursive urls (http://www.example.com/sitea/siteb/sitea/siteb/content) which can play havoc with Google PageRank. For us a secondary problem was that is caused our IDE (eclipse) to loose it frequently, presumably since it wasn't able to distinguish the symlinks from real directories and so was recursively parsing the entire drupal directory until it eventually ran out of memory. And finally symlinks don't often seem to translate well in our versioning system, which means we needed to create a script to build the symlinks across different dev environments.
What we wanted to do was achieve mutlisites on the same domain, but without using recursive symlinks. Instead our solution was to use an Apache RewriteRule for each site. eg.
RewriteRule ^sitea(.*)$ $1 [PT]
This sits neatly in the .htaccess file (before the final 'RewriteRule ^(.*)$ index.php?q=$1 [L,QSA,PT]'), and can be versioned easily.
The problem with this approach is that Drupal uses the SCRIPT_NAME environment variable (normally /index.php) from the server to figure out which site config file to use. With symlinks the server is 'tricked' into thinking it's actually accessing index.php at a different location (/sitea/index.php) than it actually is, so the SCRIPT_NAME is valid and the correct site file is found.
RewriteRules don't affect SCRIPT_NAME though. In fact we weren't able to find any way to reliably modify SCRIPT_NAME just through Apache, so instead we patched bootstrap.inc to look at REQUEST_URI instead of SCRIPT_NAME (see attached patch file). This seems to work quite well, assuming you've set $base_url correctly for each site in it's settings.php file. (Editor's note: mod_rewrite has an 'env|E=VAR:VAL' (set environment variable) flag, add that to [L,QSA,PT] as appropriate)
This solution is easilly versionable, requires no symlinks and doesn't lead to recursive URLS.
Before you use this be aware of some known caveats of this approach:
- We've tried it this morning, it's hardly a tried and tested approach. There may well be issues we haven't uncovered.
- There are doubtless more elegant ways of doing this, and we'd love to hear from anyone who has done so. Solutions from the community seems rather sparse on this issue right now though, hence this post.
- This will only work on servers that set REQUEST_URI, as far as I know only Apache actually does this
- You'll need to make sure all links in your subsites add the appropriate $base_path to them.
| Attachment | Size |
|---|---|
| bootstrap.inc_.patch | 1.3 KB |

I do this with aliases in
I do this with aliases in Apache
Alias /sitea "/var/www/html/drupal"
Alias /siteb "/var/www/html/drupal"
etc...
And the rewrite has this:
RewriteCond %{THE_REQUEST} /sitea/
RewriteRule ^(.*)$ /sitea/?q=$1 [L,QSA]
RewriteCond %{THE_REQUEST} /
RewriteRule ^(.*)$ index?q=$1 [L,QSA]
The key here is using THE_REQUEST which contains the original request before going through the alias. Doing this, I haven't needed any symlinks, and don't have to modify any drupal files. Adding another subsite just requires adding another alias line and rewrite.
Path Problem for Second site
Both the sites is working fine with changing of bootstarp.inc But the second site is not taking themes. From source code we can see it's trrying to take theme as sub folder of main site.
Main Site: basesite
Second Site: sitea
sitea ok; need help w/ siteb rewrite conds+rules in .htaccess
Hi. I have no deep knowledge of rewrite "conds" and "rules" in the .htaccess file and need help. I have no access to the apache conf file, if that's the right filename, so I cannot create "aliases" as a previous poster suggests is an alternative fix. My <my_url>/sitea/ works fine (it goes to <root>/sitea/index.php), but that is my original D6 install directory on which I want to add multiple sites and it has the original .htaccess file unaltered in it.
My public site sys admin setup my site, a virtual site I believe, so that <my_url> OR <my_url>/sitea goes to <root>/sitea/. My <root>/siteb/ directory is at the same directory level as <root>/sitea/. I've got NO index.php file in siteb/, just the .htaccess file. The base_url in the settings.php file in <root>/sites/siteb/ goes to "<root>/siteb". I have NOT set any environment variable as this page directs because I don't understand that sentence or how redirection works.
Other minutia: sitea = WLT-Drupal; it is named as <root>/sites/wlt-drupal/. siteb = WLT-Drupal-Test; it is named as <root>/sites/wlt-drupal-test/. I'm assuming case differences are not important.
I've tried the rewrite rule in <root>/siteb/.htaccess as described on this page, have made the edits to bootstrap.inc and I get "no joy" (redirection doesn't work). I get 404 "<my_url>/siteb/index.php not found". And I get the exact same 404 error if the URL is "<my_url>/siteb/install.php".
I just double-checked the edits to bootstrap.inc and they are all ok; ditto the edits (only the one "siteb" line is added above the last rewrite rule) in the siteb/.htaccess file. The two lines from the .htaccess file are:
RewriteRule ^WLT-Drupal-Test(.*)$ $1 [PT]
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA,PT]
I suspect I need some other rule(s) in .htaccess. ANY SUGGESTIONS??? HELP PLEASE. (jw: elder long-time programmer w/ lite sys admin skills)
Jennifer Woodward
MA Instructional Technology
BS/CS, BS/Math, BA/Psychology
San Francisco