a more secure drupal [multisite] install

Share/Save

I love the Drupal CMS. One of my favorite features of Drupal is the ability to do a multisite install. This site and my other blog, i <3 stella, are hosted on the same box, using the same Drupal install. Several sites can share one codebase. Updates are easily rolled out to every site simultaneously. Overall, it's a wonderful idea. But I have some problems with the implementation...

The standard way to set up a multisite install is to point each of the domain names at the Drupal install folder and let Drupal sort out which domain each request is coming from. It does a good job, too. But this method introduces some complications. For example, any content uploaded to site a is accessible from site b. A user that visits http://site1.com/myimage.jpg will find the same image as she finds at http://site2.com/myimage.jpg. Websites can't have domain specific .htaccess or robots.txt files either, which might hurt search engine optimization of individual sites.

An interesting side effect of this is if you want to install something in a subdirectory of your site, for example a WordPress blog at http://site1.com/blog, that exact same WordPress blog will exist in its full glory at http://site2.com/blog...

Another, and perhaps more grave, problem is that all that stands between the interweb and your very own personal settings is an .htaccess file. Install scripts, includes, site configurations and database passwords are in web accessible directories, and that is never a good thing.

We'll look at one solution to these problems.

I assume here that you are using Linux hosting, that you have shell access, and that you have at least a passing acquaintance with symlinks. If you're looking for a webhost that meets these requirements, check out 1and1 shared hosting. I've been happy with them, and all of their packages above $9.99/mo will do what you need.

Microsoft/IIS guys, you can't do a symlink. You're looking for something called a junction... good luck with that.

Directory structure

We'll start by creating a couple of directories. The exact location will depend on your hosting situation. Since we want to restrict access to Drupal, it's best if these directories aren't accessible from the internet. In my case, this means i'll use my home directory. Anything you type will be relative to this base directory.

mkdir drupal
mkdir site1
mkdir site2

You should prob'ly replace "site1" and "site2" with something a little more creative. Like the domain name of the sites or something...

You'll now have three folders in your base directory: drupal, site1 and site2.

Unzip the latest version of Drupal to the drupal directory. Normally, each of the domain names using this Drupal install would point to this directory. We don't want that, however. This folder will not be accessible from the interweb.

We will point site1.com at the site1 folder, and site2.com at the site2. How exactly to do this depends on your server and your webhost. For example, my webhost has a page in their control panel where I can select the destination for each domain name...

Now we will set up drupal for multisite themes and modules.

mkdir drupal/sites/all/modules
mkdir drupal/sites/all/themes
 
mkdir drupal/sites/site1.com
mkdir drupal/sites/site1.com/files
mkdir drupal/sites/site1.com/modules
mkdir drupal/sites/site1.com/themes
 
mkdir drupal/sites/site2.com
mkdir drupal/sites/site2.com/files
mkdir drupal/sites/site2.com/modules
mkdir drupal/sites/site2.com/themes
 
mkdir site1/sites
mkdir site1/sites/site1.com
mkdir site2/sites
mkdir site2/sites/site2.com

Make sure the files directories are writable (Drupal will remind you about this later if you don't do it now):

chmod ug+w drupal/sites/site1.com/files
chmod ug+w drupal/sites/site2.com/files

So far, we've got a standard drupal multisite installation. The difference here is that nobody can access the drupal directory from the internet.

Our directory structure should now look something like this:

Directory structure

Copy some important files to the site directories.

cp drupal/.htaccess site1/
cp drupal/robots.txt site1/
cp drupal/.htaccess site2/
cp drupal/robots.txt site2/

Add a settings.php file to each of the sites directories. If you don't do this, your sites will all use the "default" settings.php, and you'll be all sorts of confused.

cp drupal/sites/default/settings.php drupal/sites/site1.com/
cp drupal/sites/default/settings.php drupal/sites/site2.com/

A little magic

There are a few things in the Drupal install folder that site visitors will need to have access to. Some images and CSS files, mostly. Here's where the symlinks come in. These are special files that act like an alias to other another directory. This allows us to save disk space and upkeep time with a central codebase. But each site thinks it has it's own copy of the code.

We'll create symlinks to the shared resources we want to expose on the web.

ln -s /path/to/drupal/misc/ site1/misc
ln -s /path/to/drupal/modules/ site1/modules
ln -s /path/to/drupal/themes/ site1/themes
ln -s /path/to/drupal/sites/all/ site1/sites/all
 
ln -s /path/to/drupal/misc/ site2/misc
ln -s /path/to/drupal/modules/ site2/modules
ln -s /path/to/drupal/themes/ site2/themes
ln -s /path/to/drupal/sites/all/ site2/sites/all

Add symlinks to the files directory, so that uploaded content will be accessible as well.

ln -s /path/to/drupal/sites/site1.com/files/ site1/sites/site1.com/files
ln -s /path/to/drupal/sites/site2.com/files/ site2/sites/site2.com/files

If you plan to install site specific themes or modules they need to be linked as well.

ln -s /path/to/drupal/sites/site1.com/modules/ site1/sites/site1.com/modules
ln -s /path/to/drupal/sites/site1.com/themes/ site1/sites/site1.com/themes
 
ln -s /path/to/drupal/sites/site2.com/modules/ site2/sites/site2.com/modules
ln -s /path/to/drupal/sites/site2.com/themes/ site2/sites/site2.com/themes

Directory structure with symbolic links added

This step is crucial. If your site doesn't work, or your themes don't show up, or anything else is goofy, this is where your problem is. Visit the directories containing symlinks and type ls -al. If the symlinks show up red and/or blinking, you have a broken symlink. Try again, or redo them with full paths (something like /home/user/drupal/...).

Again, if something breaks, recheck your symlinks.

PHP files

Now we need to be able to access Drupal's PHP files from the internet (files like index.php and update.php). Since we want to change the working directory before executing Drupal's PHP files, a simple symlink isn't quite enough. Instead, we will use a PHP file that changes to the Drupal directory then includes the file we care about.

Create a new file in the site1 directory called index.php. Edit the contents of this file:

<?php
    chdir('/path/to/drupal/');
    include('./index.php');
?>

Now create a couple more almost exactly like those ones.

cron.php:

<?php
    chdir('/path/to/drupal/');
    include('./cron.php');
?>

update.php:

<?php
    chdir('/path/to/drupal/');
    include('./update.php');
?>

xmlrpc.php:

<?php
    chdir('/path/to/drupal/');
    include('./xmlrpc.php');
?>

and install.php (delete this one after the first run! you won't need it anymore...):

<?php
    chdir('/path/to/drupal/');
    include('./install.php');
?>

Copy all of these wrapper files to the site2 directory as well.

cp site1/*.php site2/

The final result

Final file structure

You now have the basis for a more secure Drupal multisite install. Now files uploaded to one domain will only be accessible to that domain. Configuration and install files won't be accessible to the bad guys so you can sleep better at night. Third party software installation is a cinch, since a subdirectory in the site1 folder won't show up on site2.com.

This technique is not just for multisite installations. It can be used for a more secure single site Drupal install as well... Just ignore everything about site2 :-).

A few last touches

Set up the site1.com domain to point at the site1 folder, and site2.com to point at site2. If you can't figure out how to do this with your web host company, drop me a line or leave a comment and i'll try to help you out.

When you configure your sites remember to let Drupal know that your file system paths are sites/site2.com/files and sites/site2.com/files respectively.

When you add shared themes and modules, put them in drupal/sites/all/modules and themes. To install site-specific themes and modules, add them to drupal/sites/site1.com/modules or themes...

Now go build your sites! Visit each site in a browser, and the magical Drupal setup process will begin. Isaac Bowman has a pretty good guide for setting up Drupal in about 10 minutes.

Comments

Hi,

I currently use drupal in a multi-site config and definately want to try your suggestion for securing drupal. Just a couple of clarifying questions:

  1. Are the top level directories created outside of the public_html directory?
    If yes then how do we get users to view site1/index.php?
    If no, then how do we make drupal not visible from the web?
  2. Is it best to use a vanilla drupal install from drupal.org or can I get cpanel/fantastico script to install?

Thanks In Advance,

JamieT

yes, the top level directory is outside of the public_html folder. this is the best case scenario. if you can't manage this, you might be able to use .htaccess or access control to limit the access to the drupal folder. but you definitely want it somewhere where it isn't web-accessible.

the way you point the domains at your subfolders is webhost specific, so i can't really answer that one. i know in Cpanel, for example, you go to "addon domain maintenance" and direct the domain name to the subfolder (i.e. site1).

i've never tried this with an automated install, since the vanilla install is so slick and easy to use... it should work just fine though. be sure to tell the installer to install drupal to the non-web accessible folder (you might have to move it afterward, if the installer defaults to a web accessible location).

I just stumbled on this thread and frankly I'm more confused than ever. I realize this entire discussion assumes a shared server. I am configuring a multi-site installation where I own the server (FreeBSD), so my current file web accessible directory that contains all of the Drupal file structure is: /usr/local/www/apache22/data

I am assuming your assertions re security of a public_html directory apply equally here, but I'd like to know exactly why this is dangerous given that the .htaccess file contains directives that prevent doing anything bad in the web accessible directory. Why is that not sufficient?

that's a dangerous assumption to make. the .htaccess file prevents doing most bad things... but not everything. it's still best to keep settings, libraries, etc. out of public view.

for example, say you edit your settings.php file from a terminal, using vim or pico. by default the old version is often saved as settings.php~. since this is no longer a .php file, apache and most other web servers will serve it as plain text. and this is a bad thing.

remember when facebook leaked a bunch of source code? any time your server forgets to run things through php first, or any time something sneaks past your .htaccess rules, you've got a security risk.

Hi again,

Everything's working ok but I noticed that the Garland theme doesn't work right as it saves its custom colors file in /drupal/files/color and not in a site specific folder even when the theme files are in the site specific folder. Did I miss something?

jeff

it sounds like your file system path is pointing to /files instead of /files/sitename. check your site settings in admin > settings > file system and make sure it's pointing to your site's files directory.

Ah yes, that was the problem. I had set the file system path back to /files from /files/site1 because I had installed WebFM and wanted the root directory for that to be /files/site1 but that only works if the file system path is /files. So I had to change the WebFM root to: /files/site1/webfm.

Hi,

Well, all is not quite well.

Before I made the changes you outlined the cron job ran fine, and it still works if you access http://example.com/cron.php with an ordinary browser, but if you use lynx or curl or even wget, it won't run the cron script. I had previously been using the cron-lynx.sh script with no problems.

For example, I tried running this from the command line:
/usr/local/bin/lynx http://example.com/cron.php

It started lynx and returned:

FRAME: http://example.com/cron.php

FRAME: /pop-src-page.script

Any idea why this doesn't work?

Also, accessing site1/cron.php only updates site1 and not all of the sites in spite of the fact that the same central script gets run regardless of which site calls it. How does that work?

Tnx, Jeff

Well, I solved the mystery. It was because I'm using IP based addressing with a domain name alias in ZoneEdit. I'm running several Drupal sites from a common code base and separate databases. I simply changed the lynx script to use the IP address rather than the domain alias "example.com" and it worked.

Here's what I posted in the Drupal forums:

One point I haven't seen mentioned elsewhere with regards to a multi-site setup: Each site has to run its own cron script. In my case I have a common code base and separate databases for each site. This might not be necessary if the database is shared.

Now for the next question - on a presumably related subject...

I noticed that the browser tab (Firefox in this case) does not show the title tag supplied by Drupal - it shows:

http://example.com rather than "Example | Imagine That!". Actually that's both the title and the site slogan - not sure how that happens.

In fact the address bar only shows http://example.com, and never any appended subdirectories. I used the developer plug-in for FF to look at the source code. There are two available under "frame source", one for http://example.com and one for http://68.107.24.241:8082.

I can't show the code here because your site is apparently not recognizing the code tags, so you can see the rest of this post here:
http://drupal.org/node/216613#comment-714359

Another interesting quirk is that the favicon never makes it and is probably related as well.

I suspect the way around this problem is not to use the alias domain name in the "C" record, but then the address bar will show the IP address which isn't especially desirable. Either way it's ugly, I guess.

This is all because I'm trying to host several websites from one IP address on my Cox cable connection. Cox as well as many other internet providers of course block port 80, otherwise this wouldn't be an issue since you could just use name based resolving in Apache. I'm using trickery to get around this by implementing IP forwarding in ZoneEdit, with the domain alias, and a separate port number for each site. Then Apache sorts it out according to the port numbers and forwards the traffic to each separate Drupal subdirectory, each with its own settings.php, etc.

It's just weird how Drupal uses frames like this and the browser sees the meta tags but possibly not the DOCTYPE. Hmmm, maybe I'll be forced to drop the alias, not that this will ever be anything close to a production site - just fooling around on the cheap to learn Drupal. Then I'll move the whole shooting match to a real server.

Wish there was another way around this... Jeff

I was wondering if you would be willing to share the script you use on your server to host multiple drupal sites that you mention in the above instructions. I am working on setting up ISPconfig and Drupal and and would like to see if I can utilize the script with ISPconfig.

Thank You in Advance.
Marty

honestly, this script was the basis for my writeup, so it's nothing you haven't seen...

#!/bin/sh
 
if [ $# -lt 1 -o $# -gt 1 -o "$1" = "--help" ]; then
    echo 1>&2 Usage: $0 example.com
    exit 127
fi
 
# set up the site directory
#   (i have .htaccess, robots.txt, and all the php include files mentioned in
#   http://justinhileman.info/blog/2007/06/a-more-secure-drupal-multisite-install
#   saved in a folder called ~/drupal/base)
cp -r ~/drupal/base ~/public_html/$1
 
# make the file directory
mkdir ~/drupal/files/$1
chmod ug+w ~/drupal/files/$1
 
# set up some symlinks
ln -s ~/drupal/themes ~/public_html/$1/themes
ln -s ~/drupal/modules ~/public_html/$1/modules
ln -s ~/drupal/misc ~/public_html/$1/misc
ln -s ~/drupal/sites/all ~/public_html/$1/sites/all
ln -s ~/drupal/files/$1 ~/public_html/$1/files/$1
 
# make the site file and edit it
mkdir ~/drupal/sites/$1
cp -r ~/drupal/sites/default/* ~/drupal/sites/$1
 
# append some stuff to the end of the new settings file
echo "\$conf = array('file_directory_path' => 'files/$1', 'file_directory_temp' => 'tmp');" >> ~/drupal/sites/$1/settings.php
 
# i usually enter the db config by hand in vim. you could easily
# echo the db config to the end of the settings file kinda like above.
vim ~/drupal/sites/$1/settings.php

I have adjusted the script a bit for use with ISPconfig.
I placed the base drupal install in var/drupal

Still some manual things to do after running the script. The folders inside the "sites" folder have to be rename to their corresponding domain names. Hope you like it so far.

#!/bin/sh
 
if [ $# -lt 2 -o $# -gt 2 -o "$1" = "--help" ]; then
    echo 1>&2 Usage: $0 webname example.com
    exit 127
fi
 
# set up the site directory
#   (i have .htaccess, robots.txt, and all the php include files mentioned in
#   http://justinhileman.info/blog/2007/06/a-more-secure-drupal-multisite-install
#   saved in a folder called ~/drupal/base)
cp  /var/drupal/base/* /var/www/$1/web/
 
# make the file directory
mkdir /var/drupal/files/$1
chmod ug+w /var/drupal/files/$1
 
# set up some symlinks
 
ln -s /var/drupal/includes /var/www/$1/web/includes
ln -s /var/drupal/misc /var/www/$1/web/misc
 
ln -s /var/drupal/modules /var/www/$1/web/modules
ln -s /var/drupal/profiles /var/www/$1/web/profiles
 
ln -s /var/drupal/themes /var/www/$1/web/themes
ln -s /var/drupal/sites /var/www/$1/web/sites
ln -s /var/drupal/sites/all /var/www/$1/web/sites/all
ln -s /var/drupal/files/$1 /var/www/$1/web/files
 
# make the site file and edit it
mkdir /var/drupal/sites/$2
cp -r /var/drupal/sites/default/* /var/www/$1/web/sites/$2/
 
# append some stuff to the end of the new settings file
echo "\$conf = array('file_directory_path' => 'files/$1', 'file_directory_temp' => 'tmp');" >> /var/www/$1/web/sites/$2/settings.php
 
# i usually enter the db config by hand in vim. you could easily
# echo the db config to the end of the settings file kinda like above.
vim /var/www/$1/web/sites/$2/settings.php

martijn,

thanks for sharing your modified script. i just have a couple of thoughts. first, what did you mean about having to rename the sites folder after the script finishes? i might be able to help tweak the script for that.

second, if you're using the wrapper .php files like i described in my writeup you don't need (nor do you want) symlinks to the following folders:

drupal/sites
drupal/profiles
drupal/includes

The argument to pass to the script is the "webname" for ispconfig. Like web5 or something. This will make the right folders, and copy the files to the "web5" folder. For a Drupal multi site environment, there should be a second argument, the domain name(s??)
That's why you will have to rename the folder /sites/web5 to /sites/somedomain.com

To bad I don't understand shell scripting enough to add this parameter. Maybe you can help me out here??

I will look into the symlinks to drupal/sites, drupal/profiles and drupal/includes. What i remembered is that it resulted in a server error 500 without them, but i will test some more soon.

Thanks for this setup, and delivering the script to the drupal community

rather than post another copy, i adjusted the script you posted above. it will take two arguments instead of one and name the sites subfolder appropriately, so it should work for you now.

What can is say, You are the man!!!!

Thanks, this script works great.

How does someone use the ISPConfig script? Is it saved into a specific file? Last bit of information I need to get my server and sites up. You're write up is one of the bests I've seen, but I'm just lost on how to integrate with ISPConfig...

Thank you in advance for any assistance you may offer.

This is a script file. Save it as something.sh...

Unfortunately I know absolutely nothing about ISPConfig, so I can't help you get it integrated. It looks like ISPConfig scripts go in /root/ispconfig/scripts/shell/. Once you figure it out, be sure to post back here to everyone else can figure out how to do it.

I am actively seeking guidance to solve this quandary and I will post the resolution once it is made available to me. In the mean time I have started a forum post on the topic at http://www.howtoforge.com/forums/showthread.php?p=155482.

BTW - Your page hurts my eyes to read. violin begins playing I was trying to read through all the posts and I started to get a headache. There is so much great info here though, so I turned off the css. Not nit picking your design, which is very nice, just making note of the distress light-on-dark copy puts on us visually challenged.

Thanks again!

If I ever get time to finish it, there's an alternate color scheme for this site (basically the reverse of this one). The problem is the time. I don't actually have any of that. So here's hoping the dark-on-light variant eventually sees the light of day :-/

I was not able to install the child sites until I added the install.php file to the redirected files.

install.php

<?php
chdir('/path/to/drupal/');
include('./install.php');
?>

This worked for me but was there another way for me to do this?

you're absolutely right... i completely forgot install.php

now that it's installed, you won't need install.php anymore, so i'd delete that file.

thanks, original post updated :)

Your instructions are clearly written. And I'm a reasonably intelligent person. At least I should be intelligent enough to follow these instructions. So how come I get a messed up configuration? When I go to one of my new sites I get the same site as the root Drupal, except no theming.

Hi Cutter,

I have just performed a multisite Drupal test install using the method Justin Hileman outlines above and have noticed the same themes issue you noticed. I also noticed a similar issue with modules, and that got me thinking about the original install instructions and that's where I noticed the bug.

Where Justin says, under the heading of "A little magic" the following:

We'll create symlinks to the content we want to expose on the web.

ln -s drupal/files/site1 site1/files
ln -s drupal/sites/all site1/sites
ln -s drupal/misc site1
ln -s drupal/modules site1
ln -s drupal/themes site1
If you have installed site specific themes or modules you will need to link to them as well.

mkdir site1/sites/site1
ln -s drupal/sites/site1/modules site1/sites/site1
ln -s drupal/sites/site1/themes site1/sites/site1
Rinse and repeat for site2.

he has made a mistake in the softlink creation statements. If you have a look in the "themes" directory of the sites, you'll notice they are empty. Same with misc and modules. To fix this, you'll need to remove the softlinks - go into each /site/ directory and run the rollowing commands:

rm modules; rm misc; rm themes

and then re-create the links correctly:

ln -s ../drupal/modules modules
ln -s ../drupal/misc misc
ln -s ../drupal/themes themes

After doing this in each /site/ directory, you'll get back the themes, misc and modules that are install-wide which was broken by following Justin's original instructions.

PLEASE NOTE that the reason this may be working for some people (Justin's steps) and broken for others (needing my steps) is most likely because of the configuration of the actual server itself. For example, in all of the php files that we create and copy above, I needed to use:

chdir('../drupal/');

as my path whereas others may well get away with:

chdir('/drupal/');

Anyway, there's muy input and hopefully this will help your themes issue.

I'm going to have a look at site-specific themes and modules a little later today as right now, if I add a theme for one site it is available to all sites, which isn't necessariloy what I want to have happen, especially where customized and/or commercial themes, modules and so on may be used.

Regards,
HiltonT
http://hiltont.blogspot.com/

HiltonT,

thanks for pointing that out. i'm sure that's what cutter was running into. perhaps i was a bit unclear in my explanation... sorry about that.

i ran each of those symlink commands from the parent directory (i.e. the one with 'drupal', 'site1', and 'site2' in it). if you run them from that directory, they should work without '../' at the front.

Hi Justin,

Yeah, that's where I initially ran them from as well, and things didn't go well. Running from in the dir worked. Weird, and totally not what I expected.

What it did (from the partne dir) was to work fine for the "site1" site but not for subsequent ones. Even weirder. I know the syntax was right as all I did was scroll back through the command history and change "sitex" names. :S

Anyway, I'm looking at maybe scripting this whole process and I'll look at those scripts already posted first, and if I come up with anything interesting, I'll post that up here.

Regards,
HiltonT
http://hiltont.blogspot.com/

weird. what's your development environment? are you running this on linux/apache/mysql/php? if so, do you know what linux distro it is?

Hi Justin,

This is a FreeBSD box that we're running it on. So, it is a BAMP box. :)

Aahhh, watching the Harmony module relocation on NASA TV right now! :)

Regards,
HiltonT
\http://hiltont.blogspot.com/

Hi Justin,

I also think that you missed one vital difference between what I did and what you did. I performed the following (from the www root successfully):

ln -s drupal/files/site1 site1/files
ln -s drupal/sites/all site1/sites/all
ln -s drupal/misc site1/misc
ln -s drupal/modules site1/modules
ln -s drupal/themes site1/themes

The difference is that I created the links INSIDE the "site1" and "site2" folders whereas you created the links TO the "site1" and "site2" folders. I also changed the "all" to be inside the "sites" dir, instead of to the "sites" dir.

Basically, I tried to keep the "sitex" directory structure pretty much the same as the original Drupal installation whereas your instructions will result in themes and modules being mixed up into the same place inside the "sitex" directories.

Regards,
HiltonT
http://hiltont.blogspot.com/

actually, we did the exact same thing... i was using a shortened form of the ln syntax:

ln [-fhinsv] source_file target_dir

since the directory (site1, site2) already existed, the command will actually create a symlink with the same name as the source file inside the target directory (site1, site2, etc.)

check out the screenshots of the resulting directory. it should look about the same as yours. unless, of course, i'm completely misunderstanding what you did...

yeah. that's exactly the problem. i just tried creating a symlink on a BSD box, and the BSD ln command doesn't allow the shortcut style syntax... i'll change my writeup to reflect that :)

Can you put the modules and themes on each site separately? Will it still work...? The rest are shared, but the modules ad themes are not.

yep. do it just like drupal suggests: create two directories inside drupal/sites/sitename. one called "themes", the other called "modules". make sure to create symlinks to these folders, otherwise the themes and modules will work, but any assets like css and image files won't show up on your site.

Thanks Justin. You rule. I will try it today and hopefully get it right. I will create a /home/drupalmulti and then do the domains there so I can use one ftp login to upload and edit stuff. It can get complicated with multiple sites especially when it comes to updating modules etc.

Thanks again,

Do you accept Paypal should I screw up? It could be the easiest $100 ever :-)

I have worked my way through the above guide TWICE with no success I cannot get a theme to load at all. After the 1st failure I deleted it all and started fresh and then when it still didn't work I followed HiltonT's directions above, still with no joy, just the same miserable results, text/no theme. So any help would be appreciated, please.

I am with Bluehost and have it set up the following way:
home/xxx/drupal
/sites/
/sites/all/
/sites/default/
/sites/default/settings.php
/sites/site1/
/sites/site1/modules/
/sites/site1/themes/
/sites/site1/settings.php
/sites/site2/ - not worrying about this one yet, trying to get site1 working

home/xxx/public_html/site1
home/xxx/public_html/site1/files 72 Bytes httpd/unix-directory 0755
home/xxx/public_html/site1/files/modcraft 0 Bytes text/x-generic 0000 (symlink)
home/xxx/public_html/site1/sites 104 Bytes httpd/unix-directory 0755
home/xxx/public_html/site1/sites/modcraft 96 Bytes httpd/unix-directory 0755
home/xxx/public_html/site1/sites/modcraft/modules 0 Bytes text/x-generic 0000 (symlink)
home/xxx/public_html/site1/sites/modcraft/themes 0 Bytes text/x-generic 0000 (symlink)
home/xxx/public_html/site1/sites/all 0 Bytes text/x-generic 0000 (symlink)
home/xxx/public_html/site1/.htaccess 4 KB text/x-generic 0644
home/xxx/public_html/site1/cron.php 66 Bytes application/x-httpd-php 0644
home/xxx/public_html/site1/index.php 67 Bytes application/x-httpd-php 0644
home/xxx/public_html/site1/install.php 69 Bytes application/x-httpd-php 0644
home/xxx/public_html/site1/misc 0 Bytes text/x-generic 0000
home/xxx/public_html/site1/modules 0 Bytes text/x-generic 0000
home/xxx/public_html/site1/robots.txt 2 KB text/plain 0644
home/xxx/public_html/site1/themes 0 Bytes text/x-generic 0000
home/xxx/public_html/site1/update.php 68 Bytes application/x-httpd-php 0644
home/xxx/public_html/site1/xmlrpc.php
home/xxx/public_html/site2

I have spent all day on this, driving me nuts so I have tried to be as explicit as possible, any help would be appreciated, thanks.

Failing this I would use the script supplied to set it up, but I am new to ssh, so if directions could be given on how to do it that would be fantastic too.

Thank you :)

Okay, after another day of playing the only way I could get it working was to move the drupal directory from /home to /home/xxx/public_html/drupal.. walla it works.. very annoying I would really rather have it the other way.

Now a problem, site1 is my main account on bluehost, which I have set up in a directory /sub/ with htaccess redirecting it. When I go to site1.com it actually brings up site1.com/sub, I have fiddled with htacess and settings. I was looking at Richard's problem above and tried adding
and files/site1
Order deny,allow
Deny from all

neither were successful I am still gaining access through both site1.com/sub/ and site1.com - to acheive the latter I have to manually drop the /sub/ in the address bar though.

Any ideas please?

NOTE: The article has been revised to resolve the symlink problems mentioned here. Thanks, HiltonT, for pointing it out :)

Well, first I wanted to thank you for providing a more secure option for a multi-site installation.
Everything just worked fine although I'm facing the same problem as mentioned in the previous comment: everything is working, except the page is text only - no theme nor image at all. They are listed though in the administer-section as well as a additional folder containing a theme-to-be-costumized.
I can exclude that it's a installation failure because the same drupal-codebase workes fine for the first domain Iused it for.
Any idea what might cause this problem?

Great article. I have followed the steps and have a couple of questions:

  1. From your write-up and reading the questions/answers it appears that there are no files in public_html. All files are to be stored in some other directory (like the /home directory). Is this correct?
  2. My sites are hosted with bluehost.com which also uses cPanel. The addon domain procedure you refer allows me to add any domain except my original domain. This makes sense since it already exists. Currently my original domain (linguaetc.com) is pointing to public_html. Have you found a way to point your main domain to site1?

Yours truly,
Richard

did you try using a redirect?

Thank you Tom for the great suggestion. Unfortunately, on the Bluehost.com redirect page they state "You cannot use a Wild Card Redirect to redirect your main domain to a different directory on your site." Accordingly, I left the main site in public_html as suggested above by Justin.

  1. that's right. we don't want drupal to be publicly accessible. in my case, that means something like this:

home/
  drupal
    ...
  site1
  site2
  site3

  1. i'm not sure (i don't usually use cPanel) but you don't need to actually call the file site1. you can use your public_html directory anywhere you see "site1" in my writeup and it should work just fine:

home/
  drupal
    ...
  public_html
  site2
  site3

Thank you very much Justin. I now have two working websites setup very close to your suggested setup. I have only two further questions:

  1. You state to tell drupal that the files are in files\rdhamilton. However, when I do this in the Site configuration screen it creates a new folder called files\rdhamilton under drupal. How do I get the program to know that my files are stored in a subdirectory of files called rdhamilton?
  2. I have themes working on both websites. However, I cannot change the themes through Site building - Themes. The only way I can change it is in the settings.php file. Any suggestions?

The following are a few observations that I would like to share for anyone else using this setup (I also welcome comments and suggestions):

  1. Per your suggestion I used public_html as site1. I had thought we wanted everything out of public_html this is why I was trying to find an alternative.
  2. Bluehost.com insists on pointing the add-on domains to public_html. Therefore, I created a symlink pointing rdhamilton in public_html to rdhamilton (aka site2) under the /home directory.
  3. I created new databases and ran install.php for each website. I thought I would try to use the existing databases but it kept throwing errors. If someone has done this with existing databases maybe they can share how they did it for others.

Thank you again.

  1. try telling it the directory is files/rdhamilton (forward slash instead of back). let me know if that works.
  2. i know if you set it in settings.php you can't change it through the drupal admin panel. if you remove the line in settings.php, does it let you change it via drupal?

You are good...

  1. Drupal accepted the files/rdhamilton without any errors or creating a new directory.

    a. But when I try to access the file through http://www.rdhamilton.com/drupal/files/ it gives me a 404 error. I even tried to include a file in the directory and access it with http://www.rdhamilton.com/drupal/files/actualfile I have the temporary directory set to /tmp and download to public.

    b. For security, do you set the download to private?

  2. Removing the line in settings.php allowed me to change it via drupal. Thank You!

the files should actually be at

http://rdhamilton.com/files/rdhamilton/actualfile

and i don't use private download, personally.

so your directory setup looks something like:

drupal
public_html
  ... all the basic multisite files
  rdhamilton -> link to rdhamilton
rdhamilton
  ... all the basic multisite files

and domain 1 points to public_html, domain 2 points to public_html/rdhamilton, right?

if this is the case, you'll get weirdness if anyone ever goes to site1.com/rdhamilton ... it will still be site 1's content, since drupal decides what content to serve based on the domain you ask for. but it will essentially give you two different paths to every page in your main drupal site. try it. site1.com/rdhamilton should look identical to site1.com.

if this is the case, you're going to want to block /rdhamilton for traffic coming to site1. that'll make sure none of the weirdness ever surfaces. add the following to your site1 .htaccess file

<FilesMatch "^rdhamilton">
  Order deny,allow
  Deny from all
</FilesMatch>

You are absolutely correct in my setup. You are also correct, when I go to linguaetc.com/rdhamilton I see the linguaetc.com content.

I have added the lines in the linguaetc.com .htaccess file (located in /public_html). I tried adding them below and then above the existing FilesMatch lines:

<FilesMatch "(\.(engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)|code-style\.pl|Entries.*|Repository|Root|Tag|Template)$">
  Order allow,deny
</FilesMatch>

Now when I type linguaetc.com/rdhamilton I get a 403 error...Actually this turned off all access to rdhamilton.com With the suggested FilesMatch lines I receive a 403 error message when I try to access any of the rdhamilton.com website.

Any ideas?

Hi Justin,

I just emailed you, but as I reread the comments, I found someone had actually already posted the same question.

I do have one more question, though.

I now get it that instead of creating a new directory called site1, I can just skip the mkdir site1, and go right to creating the subdirectories within public_html.

But, am I right that I still need to do mkdir drupal/sites/mydomain.com (that is, I still need to let drupal know the actual .com name of the install?

Thanks, and please keep up the good work here!

Josh

nevermind...I tried it, and it seems that I was correct :)

Great job! I really appreciate the time you took placing the pics and images. I found your post off of your comment on my older article Installing a multi-site system on Drupal in less than 10 minutes. I would like to use Drupal as my own personal DM (document management) Sys the same way some people use Gmail to store and search for notes.

thanks :)

i actually have a local drupal installation that i use for document management, personal wiki, etc. it's working out great for me.

Hi, thank you so much for sharing this tip. Though I'm a relative newbie, I can see that this is a better way to do a multisite installation...except that I run into the same problem that a couple of folks here have mentioned in the comments (for which I didn't see any reply... :)
- that is, I get an installation page (and all subsequent pages) without any theming at all! I tried making additional symlinks (just in case) for the 'script's and 'profiles' folders, too...but no luck. Would really appreciate some help - if you can think of a reason why there's no theming...Thanks.

the scripts and profiles folders shouldn't have symlinks. those include only back end code...

if you run into unthemed pages, whether in installation or in your actual site, you've most likely got a missing or malformed symlink.

the good news is that your site will work just fine without the symlinks. it'll just be ugly. the bad news is that sometimes symlink issues are a bit of a pain to track down.

here's how i usually do it:

  1. view source on the page that's missing styling
  2. find the css includes, and open up each css file in a new tab/window
  3. if none of them load, start over with the symlinks (basically redo everything under the heading "a little magic" above)
  4. if some of them load, look for a common theme: are the broken ones under "sites/all"? am i mostly missing module or theme css files? this usually tells me which symlink needs to be fixed

Hi Justin,

Great tutorial! You got my multi-site started up and it seems to be working but this same problem of no theming at all (installation nor homepage).

I've double checked and have redone the symlinks but still not working. And the only clue is that E.g. drupal/themes/garland/logo.png shows but not site1/themes/garland/logo.png Can you advise? Thanks in advance!

that is almost always a symlink problem... does your ssh program use color? if so, a broken symlink will be red, possibly blinking. if not, you can try navigating through a symlink on the command line:

cd site1
cd themes
cd garland
ls</pre>

if you make it to the directory, and actually see something, then you're doing alright... otherwise, you need to redo your symlinks.

Justin, you are right! My ssh proggy shows red. I had to symlink them to "/home/xxx/drupal/..." instead of just "drupal/..." Now it's green! Thanks!!

Now I get the logos n stuff but still no theming... is it becoz the css is broken?

Hi! I looked at the error logs and found the 404 errors all originated from those in the files folder.

It turned out that the symlinks were all working and it's just my files folder permission was not executable. I just changed the permissions and voila! nice. Thanks again, Justin!

Thanks for your tips. It helps me build two domain sites for my client.

no problem. i'm glad to help :)

Hi Justin,

I don't like the new "200 pixel wide" fixed width theme you've deployed - it may have been appropriate back in the olf CGA days, but everyone has MUCH higher resolution monitors now, and it almost makes this page look like a cigarette on a tabletop. :)

  • HiltonT
    http://hiltont.blogspot.com/

if you don't like this one, you should check out my scooter blog :-)

Hi Justin,

I really have to wonder why you'd want to use a theme that's as narrow as this - let alone the scooter one - when all it does is make the use of any current monitor (as in current in the last 20 years) utterly redundant.

Having a 2" wide strip down the centre of a 1280*1024 (or higher res) display makes, to me, the site look silly.

Not to mention that breaking each sentence up into almost individual words makes reading harder and slower.

Anyway, each to his own - it is your site and your theme choice. I thought you may just like some input from users on their thoughts on ultra-skinny themes.

Regards
HiltonT
http://hiltont.blogspot.com/

Hi Justin,

I've now finally got the chance to look further into your method and have one issue that needs to be resolved.

Right now, if installed as described above, if I install a theme or a module in any site it is available to all sites, which won't be good if I install a commercial module or theme for one site and it is then available for other sites to use without paying for it. What I'd like to be able to do is to be able to install global themes and modules as well as site-specific themes and modules.

You do start to mention site-specific modules when you say:
If you have installed site specific themes or modules you will need to link to them as well.

mkdir site1/sites/site1
ln -s drupal/sites/site1/modules site1/sites/site1
ln -s drupal/sites/site1/themes site1/sites/site1

Rinse and repeat for site2.

but this drupal/sites/site1/modules isn't there in a fresh install, however I gather creating it now before needing it will be fine. I also gather you can do the same thing for themes.

OK. I just did the following and it worked exactly as I expected:

mkdir drupal/sites/site1/modules
mkdir drupal/sites/site1/themes
mkdir site1/sites/site1
ln -s drupal/sites/site1/modules site1/sites/site1/modules
ln -s drupal/sites/site1/themes site1/sites/site1/themes

Rinse and repeat for site 2.

Install a new theme to site1/sites/site1/themes and select this theme as the default (we want to know it is working)
Configure themes for site2 and this site1 theme is not available.

Excellent - that allows me to have site-specific themes (and I assume, too, modules) and also global themes (and modules).

Regards,
HiltonT
http://hiltont.blogspot.com/

Justin,

Thanks for this. It's been very helpful.

Any particular reason you've put files in
   ~/drupal/files/site[n]
instead of
   ~/drupal/sites/site[n]/files

The latter seems to be the convention.

Thanks,

Sam

mostly because when i started using this method for my multisite installations, there was no such convention. all modules were installed in the main drupal/modules directory, third party themes were likewise intermingled with the core themes. and files were usually dumped in a directory under drupal. it's stayed in the writeup because i've continued doing it this way.

either way should work just fine. in fact, it would prob'ly be easier to maintain if the files were under ~/drupal/sites/site[n]/files.

with the latest update to my guide i've moved the files directories to ~/drupal/sites/site[n].com/files... now it matches up with the current convention and will be easier to update.

Hi Justin,
why would I get a PHP Warning: include(./install.php) [function.include]: failed to open stream: Permission denied in /home/mysite/subsite/www/install.php on line 4 (apache error)

any idea? This is after doing all the copying and going to the /install.php to setup the new db. Is there a switch or change in the main install.php I need to change?

I also sent an email regarding something else.

Thanks,

Hi,

I want to use drupal for my new site, and also a "sandbox" sub-domain for trying out ideas, and also for a second domain that that has been added to my account as an add-on domain. The account has Cpanel.

Your guide looks like just the information I need..
except that reading all of the comments I'm now a little confused - I'm new to all of this! Any chance of a revised guide including all of the changes to the original?

Cheers

i plan to make a clarified, simplified writeup on of these days... unfortunately i don't have as much time as i'd like. but the current guide does include all the changes discussed in the comments. for example, all of the symlink problems Hilton T brought up have been updated, so there won't be problems with that on BSD systems anymore.

Heya, great guide...

Couple questions though:

I seem to be getting a unified theme and user DB across my two sites. In other words, they're the same site. Any idea how this could happen? My symlinks seem okay.

Any chance you could share the site-maker script? :) It would be mighty neat.

Cheers,
Yorick

Actually just to also add: I have checked the database settings in settings.php and they're using the same table, but with a different prefix. Will the default settings in the 'default' site make any difference?

it's hard to say what the problem is without knowing more about your setup. my guess is that it has something to do with the order of precedence in drupal's domain/site name resolution (i.e. it checks first for a site definition for the folder, then for the subdomain, then for the domain, then uses default if all else fails)

are the two sites using the same domain or subdomain? are they installed in folders off the domain?

I have similar problem. It for the multisite even i deleted the settings.php, it keep pointing to default folder that have settings.php. I don't know what happen. it will not work if i delete settings.php on default folder.
I do the symlink with eg. i go to the folder A -> cd A and then ln ../drupal/modules modules. this is working well with the css and theme but only I can't install because it point to settings.php under default folder
but when I do the symlink with eg. in the root ln /drupal/modules /A/modules. I can't get the themes and all css working. Also it takes the settings.php from default folder. it's say drupal is installed

Please help me
Thanks

I didn't try this setup myself yet, but it seems a very interesting way to improve my multisite setup. There is just one thing I wonder: why don't you use symlinks for the php files too? (index.php and all the other ones you use an include for)
Is there a particular reason for that?

actually, yeah. if you just symlink them, the current working directory is your web directory. that means when they look for includes, config files, etc, they look for them in your web directory... the wrapper files change the working directory to where your drupal install really is, so everything is relative to that directory. that way all the magic works.

I've tried to follow all your instructions and this is what I get when I go to my subdomain. Any ideas on what I am missing?

Warning: main(./includes/bootstrap.inc): failed to open stream: No such file or directory in /home/content/html/drupal/index.php on line 12

Fatal error: main(): Failed opening required './includes/bootstrap.inc' (include_path='.:/usr/local/lib/php') in /home/content/html/drupal/index.php on line 12

I got it... I ended up deleting everything and starting over. Apparently I missed something the first go around!

This time it worked like a charm. Thank you so much for sharing!

no problem. i'm always excited when things just work :)

One more question -

Is there a way to use this in conjunction with the MultiDomain / Single Logon modules to administer and create content on the main to be sent to the subdomains?

i imagine it's possible... i haven't tried it though. why don't you give it a shot and let us know?

Ok guys a quick question: My css /other files are broken when I choose the templates or modules from the /all folder (it is suggested that shared modules for sites be put there.)

From drupal's log:

page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.js
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/themes/original/original.cs ...
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.css
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.js
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/themes/original/original.cs ...
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.css
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.js
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/themes/original/original.cs ...
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.css
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.js
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/themes/original/original.cs ...
page not found 01/16/2008 - 03:25 sites/all/modules/simplemenu/simplemenu.css
page not found 01/16/2008 - 03:23 sites/all/modules/simplemenu/simplemenu.js
page not found 01/16/2008 - 03:23 sites/all/modules/simplemenu/simplemenu.css
page not found 01/16/2008 - 03:23 sites/all/modules/simplemenu/themes/original/original.cs ...

page not found 01/16/2008 - 03:23 sites/all/modules/recipe/recipe.css

I have a link to ../sites on /home/myname/drupal/drupal-5.6 .Any ideas? I am going nuts and I cannot add any more sites without figuring it out.

Thanks

according to a better look at the logs, apache tries to access the file with this path: http://www.mysite.com/sites/all/modules/fivestar/fivestar.css

On the http://www.mysite.com/sites/ (or better, on the unix equivalent) I do not have an "all" folder; I simply have the sitename.com folder. Should I create it? If so, do I s-link to the the /home/mainfolder/drupal/sites/all ?
Please advice, I am stuck as I cannot new sites, and I am stating to question this whole setup.

Thanks,

Thanks,

it looks like that's exactly your problem... if you're missing the symlink to sites/all, none of the css or images from shared modules or templates would show up. there should be a symlink to drupal/sites/all in mysite.com/sites

so, from the mysite.com/sites folder:

ln -s /path/to/drupal/sites/all ./all

justin this is great thanks and from a "newbie" perspective it was very easy to follow - thanks!!

one problem is that some files don't seem to be translating over.. error log as follows:

page not found 24 Feb 2008 - 3:00pm misc/powered-blue-80x15.png admin
page not found 24 Feb 2008 - 3:00pm themes/garland/logo.png admin
page not found 24 Feb 2008 - 3:00pm themes/garland/print.css admin
page not found 24 Feb 2008 - 3:00pm themes/garland/style.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/system.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/system-menus.css admin
page not found 24 Feb 2008 - 3:00pm modules/user/user.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/defaults.css admin
page not found 24 Feb 2008 - 3:00pm modules/node/node.css admin
page not found 24 Feb 2008 - 3:00pm misc/powered-blue-80x15.png admin
page not found 24 Feb 2008 - 3:00pm themes/garland/logo.png admin
page not found 24 Feb 2008 - 3:00pm themes/garland/print.css admin
page not found 24 Feb 2008 - 3:00pm themes/garland/style.css admin
page not found 24 Feb 2008 - 3:00pm modules/user/user.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/system-menus.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/system.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/defaults.css admin
page not found 24 Feb 2008 - 3:00pm modules/node/node.css admin
page not found 24 Feb 2008 - 3:00pm misc/powered-blue-80x15.png admin
page not found 24 Feb 2008 - 3:00pm misc/feed.png admin
page not found 24 Feb 2008 - 3:00pm themes/garland/logo.png admin
page not found 24 Feb 2008 - 3:00pm themes/garland/print.css admin
page not found 24 Feb 2008 - 3:00pm modules/user/user.css admin
page not found 24 Feb 2008 - 3:00pm themes/garland/style.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/system-menus.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/system.css admin
page not found 24 Feb 2008 - 3:00pm modules/system/defaults.css admin
page not found 24 Feb 2008 - 3:00pm modules/node/node.css admin

i did and re-did the "ln -s" thing twice and it's still doing it.
your or anyone elses help appreciated please!!

cheers.

tried to delete the whole thing and start over but it won't let me remove the settings.php and another one. grrr!

should have waited for a response here as starting over is going to be a pest.
any ideas on deleting the /sites folder?

thanks!

once you install drupal changes the permission on the settings.php file... you have to give yourself write permission on it again before you can delete the file. from the sites/sitename folder:

chmod o+w settings.php

that will let you delete the file

as far as your other problems, i'd be willing to bet that you have a broken symlink. does your ssh program use color? if so, are the symlinks in red?

hey thanks for that - got it deleted finally.

and i'm using putty so i can't tell colo(u)rs. i'll put my money on it that you're right, but i don't know how to fix it.
what other program should i use?

if i do "dir" in putty i can see:
total 24
-rw-r--r-- 1 u5555559 ftpusers 86 Feb 23 23:42 cron.php
-rw-r--r-- 1 u5555559 ftpusers 87 Feb 24 03:00 index.php
-rw-r--r-- 1 u5555559 ftpusers 89 Feb 23 23:42 install.php
lrwxrwxrwx 1 u5555559 ftpusers 11 Feb 23 23:53 misc -> drupal/misc
lrwxrwxrwx 1 u5555559 ftpusers 14 Feb 23 23:54 modules -> drupal/modules
-rw-r--r-- 1 u5555559 ftpusers 1627 Feb 24 02:40 robots.txt
drwxr-xr-x 3 u5555559 ftpusers 38 Feb 23 23:55 sites
lrwxrwxrwx 1 u5555559 ftpusers 13 Feb 23 23:55 themes -> drupal/themes
-rw-r--r-- 1 u5555559 ftpusers 88 Feb 23 23:42 update.php
-rw-r--r-- 1 u5555559 ftpusers 88 Feb 23 23:42 xmlrpc.php

righto leart a few things today!

ls -gal --color

and i think it needed the "full directory" before drupal in the symlinks...
works as follows:

u45555555:~/site1/sites > ln -s ~/drupal/sites/all all
u45555555:~/site1> ln -s ~/drupal/misc misc
u45555555:~/site1> ln -s ~/drupal/modules modules
u45555555:~/site1> ln -s ~/drupal/themes themes

i was just going to say that this was where your problem was :)

in the writeup, every terminal command should be run from the base directory. if you do it from the base directory, these work:

ln -s drupal/misc site1/misc
ln -s drupal/modules site1/modules
ln -s drupal/themes site1/themes

if you're running the link command from site1, you need to use a path that will link to the drupal folder location. in your case (and mine), you can use ~/drupal, but that doesn't work for everyone... some would need ~/public_html/drupal or some other path entirely.

databases - is it correct that this method uses just 1 database instead of 2 which the "normal" mulisite config does?
as you can imagine this would pose a problem with 1&1 and their limit on single db sizes!

your thoughts?

this method can use either one or multiple databases. i'm hosted on 1&1 so i use a new database for every site i install.

as a side note, you'd be surprised how much site you can fit in a 100 meg database. this site uses 4.1 meg (mysql 5) or 4.8 meg (mysql 4).

i'm new so i'll believe you on db size. when i had it setup before it was pretty small i admit, although no content at that time.

how do i use multiple db's in this instance? i'm also using 1&1

cheers!

hi justin,

still stuck at this step if you could please help.
thanks!

sorry to be more specific:
i did exactly as you described (it just makes sense to do it that way!), however if i setup one, it also flows onto the other site. it's as if each domain looks to the same the setting.php??

it sounds like you haven't set the sites folder up properly... check this page for more info.

i'd start troubleshooting by moving the sites/default folder to sites/default.bak or something. then add a blank file called settings.php to each of the folders: sites/site1.com, sites/site2.com, etc.

  1. create a new database for each site using 1and1's "mysql database" page. take note of the username, password, server, and database name
  2. point each of your domains at their respective folders (site1, site2) using 1and1's "domains" page
  3. visit each site in a browser, and drupal's automatic installer should show up
  4. enter the database information (from the first step) for each respective site
  5. let the automatic installer finish...

and you should be good :)

Thanks for putting this together.

I've been able to setup multisite as follows:

sub.domain.edu
sub.domain.edu/site2

However, when I'm in the admin section for site2, any changes I attempt to make are global. Such that if I'm here: http://sub.domain.edu/site2/admin, clicking on any option in the admin panel brings me back to here: http://sub.domain.edu/admin/...

Does multisite allow you to have multiple sites that can each be administered independently of one another?

yep. i think you'll find that you're editing the same drupal instance... you have a built in namespace collision, since site2 is "inside" your main site. this is far from ideal.

check something for me. do you have more than one settings.php file? you should have one at drupal/sites/sub.domain.edu/settings.php and one at drupal/sites/sub.domain.edu.site2/settings.php

My main domain is site1.com. I've asked my web host to point site1.com at the site1 folder and site2.com at the site2 folder. However, they can't change the main domain to a pointer. Do I need to change site1.com and site2.com into domain pointers so that they can point to the site1 and site2 directories? In that case, what do I need to do with my main domain? Hope this isn't too confusing....

Is it possible to have something like single sign on with such setup ?

the interesting thing about this setup is that Drupal doesn't realize that anything's different... so you can do anything that you could normally do with a regular Drupal multisite installation.

These are wonderful instructions and worked out of the box.

For a newbie like myself, the only instruction missing was a clarification that more multiple independent sites we want the 'settings.php' in the main drupal/sites/newdomain for each new domain.

Once I got a separate 'settings.php' file for each site and edited it, I was able to point my browser to the URL of the 'install.php' for each site and I was off to the races!

I know this was mentioned in the comments as an answer to a question, so I wanted to put it up front for all other new comers.

Thanks again.

"... a clarification that more multiple independent sites..."

The above should read "..a clarification that for multiple independent sites..."

Also, I use 'site' and 'domain' interchangeably in a loose manner because it's not important for this example.

thanks for pointing that out... updated :)

First thanks to the documentation

i was on way to figure it out by myself but im new to drupal and i dont want to experiement without confirmation there will be no other problems in future (with modules or something else)
so i looked in many forums and search engines and find your great doku which will save much time

im sadly see the comments by users dont know what ln -s do or how to use it and see wasting your time to support that easy way :-)

but one thing i dont like
you make such a big advertisement for 1&1. i hope you get paid for that... ireally hope (because i hate them, they are the providers from hell... i was there with 5 root servers years ago... problems from hell a lot, costs beside from good and evil and support hmm what is support...)

and if they dont pay you hmm in that case we have to talk ggg

PS: i forgot (and ife said it in the drupal forum 20 min ago) your documentation must find his way to the official drupal doku
as an extendet second way for install

its really better secured and as you wrote bevore there are so many many argument for it it should be standart install anyway

the ironic part: typo3 still work exactly that way. there you have install 2 pack anywa. one maincodebase and one skeleton for the website (also with symlinks lol oh yes we all love iss copatibility lol)

so i cannot understand why the drupal projekt waste so much time in sorting out domains by drupal self and not going the clean way
one skeleton each website (or for one website) and one hidden codebase

One thing not mentioned is about the database.

It sounds like we use the same database for both sites in this tutorial.

That may be fine, but as a newbie I am thinking of possibilities.

Would this work if we defined a separate database for each site1 and site2.
I believe this is done in the settings file.

The advantage of a single database is simplicity. A disadvantage is that damage to the database will affect all sites.

Any thoughts?

actually, this doesn't address the database question. i leave that one to you. you can use either approach, and this method will work just fine :)

i, personally, have a unique database connection for each site i set up like this. it makes it easier for me to back up and restore, and i haven't had need to share tables between sites (which is the primary reason for a shared database). so decide which will work best for you and use that approach.

Hi Justin, Great tutorial, thanks!
I actually run 5 drupal websites, using standard multisite config. I love your way of managing multisites, so I'm planning to change all my config to your way.

Not to mess with my current live websites, I setup another drupal core files folder, and will be building from there.
I did the procedure mentionned in this article, works perfectly for a new site (new DB). I'm having trouble setting up a site in the new structure using an active Database.

I got to the install page, but when all was done, got the blank page! It seems to work fine if I use a new DB, but with the active DB info in the settings.php, I get nowhere!

Do you have any ideas?

Thanks a bunch!

that's interesting... i haven't had any problems moving sites into this setup—or back to a standard multisite config, for that matter.

for an existing site, you don't even need to go to the install page. just add the db info to your config file and go.

if it's just showing a blank screen, my bet is that you have a WSOD.

Hi Justin

Many thanks for sharing this; it's just what I need.

Regards
David

I have an issue with the initial database setup..
I have the settings.php in my new site (drupal/sites/site1.com/settings.php)

But the installer is still looking at the file in the drupal/sites/default/settings.php)

How do I force it to my site1.com/settings.php

it sounds like the site1 folder might be misnamed... that's the sort of thing Drupal does when it doesn't know which site belongs to the domain. do you have an interesting domain setup? (subdomain, drupal in a folder, etc.)

Thanks for the quick response...and the idea
I had to debug the conf_path function to see the problem. I am using my dev box with the IP (1.1.1.1) and the directory is named (site1.com) Obviously it won't find it!!
So what's the work around for this?
I saw a patch for 7.x
http://drupal.org/node/231298

you can try adding site1.com to your hosts file. that should work... i haven't tried though, so let us know if that's the answer :)

This is a very helpful post/thread. Justin, is there a limit on the number of sites one could set up using this technique? I am working to set up websites for a multi-branch library consortium, and I need approximately 35 different sites (most of them very small), but I'd like them to run on a single code base if possible, for ease of maintenance. Would that be pushing it, do you think?

The most I've heard of using a setup like this is ~700. That's not to say it can't be more than that, it's just the most I've heard of.

For smaller sites, serving hundreds of domains off the same Drupal codebase isn't unheard of. One Drupal site with 1000 visitors per hour would be effectively the same thing as 10 Drupal sites with 10 visitors per hour.

The limit will most likely be in your hardware rather than Drupal. As long as your server can handle the load of all 35 sites independently, you will have no trouble handling them together.

Hello Justin,

So many Drupalers and only one (you) that give the right documentation of this multisite feature. So a gold olympic medal for you!
Moreover, I as a stranger in Drupal paradise, did understand your explanation very well and could follow every step.... Now one thing was not clear: Does the Drupal drupal/sites/default/ contain their settings.php script or should this folder stay empty?
So I'm talking about the installed Drupal folders, like they come with their installation.
Of course I did understand, that each site.com folder should contain their own settings.php script, but should the drupal sites folder contain one too or not?

Hope you'll give a quick answer, in order to end my uncertainty and stop eating my nails...;-)
greettings Felix

actually, when i'm using a multisite installation i remove the sites/default folder entirely. that way i can tell if drupal is trying to use that one instead of the more specific site folder i want it to use.

Hello Justin,

Thank you. Quick and clear reply. You've helped me a lot!

Felix

Hi Justin,

First of all thanks for your article, this gave me idea about how the multi-site should work. I am newbie in Drupal and got this multi-site tasks on my hand. We had a drupal website which my client wants to be converted to multi-site.
Ealier structure was like the basic drupal structure with "files" folder under our root directory.

We followed your steps and created another directory for different domain i.e. "site1". Create directory "sites/site1/files" under both drupal installation folder and this newly created "site1" folder.
We created all the symlinks as mentioned in your article.

After this I created Virtual Host pointing to newly created "site1" folder. Now in my database we "nodes" with data like "/files/image/arrow.gif". Now when I try to run URL http://mynewdomainURL(site1)/files/image/arrow.gif then I get page/file not found error. I have "image/arrow.gif" under sites/site1/files folder.

To solve this issue, I applied a work around where I created "files" directory under "site1" directory and copied the .htaccess file under this folder where I wrote redirection rule to "sites/site1/files" directory.

But this dosen't look like a proper solution. Can you please guide me what would be the best approach? OR I am missing anything out here?

Many thanks
Vikas

I also thank you for all the work you put into this.

I set the whole thing up, under a subdomain and all works fine when I go to mydomain.com/site1 or mydomain.com/site2.
When I set up a new domain name and map it to mydomain.com/site1, I can't see anything as if the site1 directory didn't exist.

Is there something I am missing? I hope I explained my problem clearly.

Thanks again,
Paul

Hello Justin,

I?m afraid I did something wrong. I?m getting a Page not found-error when I open mysite.com. I checked all the folders, but they are correctly in their right places, according to your script. The symlinks are in their correct locations too. I think the index.php script is the disturbing file. Here?s the code of the first 2 lines:

chdir('/http://www.mysite/drupal/');
include('./index.php');

I?ve tried almost every combination, but after all this should be the correct path as drupal sits in the root next to site1 with the index.php file. But obviously no file is passing.

Linux system, PHP5.

What could I do?
Felix

that chdir is a system path, not a URL... it should be something like "/home/myuser/public_html/drupal" or "/var/www/drupal". there's no http allowed :)

Hello Justin,

Yes, you gave me a hint, but the right path was:
/var/www/vhosts/sitename.com/httpdocs/drupal
Now the URL points to drupals install.php but the browser gives me a 403 Forbidden error: You do not have permission to access this document. Almost there, but not yet. I made all documents chmod 777, made the drupal folder chmod 777, but no result.

Have you any idea how to get access?
Sorry for all those questions, but it looks this would be the last curve before the finishline.
Greetings,
Felix

Thanks for the excellent multisite tutorial, Justin. Nothing can come close to it in simplicity, clarity and scope. There are a few thoughts that I wanted to share about it:

  • it may be important to note that the ln -s commands will not work the way they are listed the first time in the text but the ones that use ~ for relative paths in your script do
  • I use cvs for installing Drupal and that works very nicely, especially when it is the time to upgrade, so that is much better than downloading Drupal as a compressed tarball
  • have you tried this procedure with Drupal 6? I tried it and ran into trouble with the default.settings.php file, which is new in this version. I was able to rig it up but do not like the way it turned out so I wanted to see other people's experience with that.

Keep up the good work!

you're right about the symlinks... i reworked the example to make it better on BSD based servers, and it seems i broke it in the process. it's late, so i might still have it wrong, but i believe i have it sorted out now :-/

i use the tarballs, but i don't use them like most people. i actually have a copy of every drupal release since 4.3 sitting side-by-side on my server, so when the new one comes in i untar it and point my site at it. that makes it really quick to roll back if something goes wrong. quick like seconds.

i've got this going with several drupal 6 sites as well. i haven't had any problems... i believe i usually touch settings.php in the new site directory, then set it writable before i run the installer.

Hi Justin,

Having at least a couple of previous versions of drupal sitting on your server is a good idea to roll back to if a problem arises. Back to drupal 4.3? You must be a safe guy :)

My question is how do you do this with all your symlinks? There are a lot of symlinks pointing around, do you have an automatic way of updating those or do you just update them all manually in succession, pointing each to the new (ie drupal-6.12 (released today!) folder)?

Thanks,
mrax

hmmm, why did I ask that? I'm not sure - it wasn't that hard. I've worked out the answer (or at least an easy way to make it work) for myself. You don't have a drupal-6.12 folder for your core files, you have a "drupal-current" folder (or equivalent) and just rename your folders around that, aware that whatever folder is called "drupal-current" is the one which has the code which is serving the drupal site (because all the symlinks point to "drupal-current")

Great article!

It was hard for me, but I'm new with Linux. Anyway, what you're saying is spcified a bit further at:
http://drupal.org/node/476544

Hi Justin,

The index.php is not including the requested files. Instead the browser shows a 403 Forbidden error. There are no files loaded in the site1.com folder. The path to the drupal folder is ok. Symlinks ok. Just the 5 files from the drupal folder don't show up (index, cron, update, xmlrpc and install).
I really do appreciate your expertise.
Greetings,
Felix

do you have Options +FollowSymlinks enabled in your .htaccess file?

Yes, it is enabled, in both drupal folder as well as in the site1 folder.

I followed your instruction and uploaded a ready drupal multisite to hostmonster. I had problems (access denined error 500) but after changing the .htaccess file managed to see the site WITHOUT the theme. All the data were displayed in a white background but no theme. What is the problem???

most likely a missing or broken symlink.

if you're missing a stock theme, open an ssh connection, go to the site1/sites folder and type ls -al... if any of the links are red or blinking, they're broken. if they aren't red or blinking, it's possible that your terminal emulator doesn't show color, and they might still be broken :)

check if there's an "all" symlink. if there is, remove it and try again:

rm ./all
ln -s /path/to/drupal/sites/all ./all

if you're missing a custom theme, check the symlinks in site1/sites/site1.com.

OK I managed to correct the problem. It was the symbolic links that were not correct. The main problem now is I can not rotate the banners of the marinelli theme I use under my site directory.
GREAT TUTORIAL...

Hello,

Like everyone else, I'd like to begin with a thanks for putting this tutorial together. I am a complete newbie, and greatly appreciate it.

Unfortunately, I'm just not getting it. I understand that the drupal folder will be in my home folder, so it's not accessible. What I'm still not getting is the rest of the stuff. Are the folders site1, site2, et al, also in the home folder or in my public_html folder? If I reading this correctly, they are all in the home folder. Now, assuming I'm correct, then I need to tell my account that when it sees www.site1.com, that it should go to home/site1 instead of public_html/site1. Is this correct?

Now, here's the other part. I have several domain names that I'd like to run Drupal on (thus my desire to use multisites. But I also have one domain that I want several subdomains with their own instances of Drupal. I'm assuming that I can do this, too, the same way.

But again, I don't get how to point the internet to my private folders. Can someone please help?

Also, to be honest, all this site1, and site1.com is very confusing. As such, here's the actual URLs that I'm dealing with: www.joshuabuck.com is my main site (but I want Drupal on www.joshuabuck.com/main). I also want a subdomain called theblog.joshuabuck.com. Finally, there is a separate domain called www.theduelingquill.com.

Joshuabuck.com is my main site on HostMonster (although at the moment joshuabuck.com and theduelingquill.com are still at GoDaddy, and waiting to be moved over for real to HostMonster.

Thanks,

Josh.

subdomains can be treated just like they're separate domains. in your situation, i'd set it up something like this:

home
  - drupal
    - sites
      - theblog.joshuabuck.com
      - joshuabuck.com.main
      - theduelingquill.com
  - theblog
  - main
  - theduelingquill

you can choose whatever names you want for the subfolders under home, but you have to use those exact names for the subfolders under drupal/sites (also known as config folders). for more info on naming the config folders, check out this blog post.

now point your domains at theblog, main and theduelingquill (the subfolders under home).

if it helps, do a search and replace on this article, and replace every instance of "site1.com" with "theblog.joshuabuck.com", "site1" with "theblog"...

Thanks for the clarification.

I still have one more question. I followed everything, and then I went into public_html and did ln -s /home/theblog theblog.

But I get a message saying I don't have permission to access. Did I forget a step of granting permission somewhere? The install.php perhaps?

I know I can do this, I just need to buy you a little more :)

Thanks again for your help.

that should be bug you a little more...but I'll be happy to buy you a drink when I finally get this thing up and running properly.

OK, so once you actually do the symlinks CORRECTLY, everything works just beautifully. I was trying to figure out why my symlinks were showing up red...then it occurred to me that maybe red wasn't such a good color, so I deleted all of them and did the ln -s with a full path to the folders and voila! All is good in my virtual world.

Thanks again, Justin. I really appreciate your hard work here!

Honestly, that's almost always the problem. I've added a comment to that effect in the writeup, along with a suggestion to try full paths. We'll see how well that works :)

Justin,

I was just thinking...can this be done with Wordpress as well (not the multi site, but putting it in the private folders and symlinking it? Do you or anyone else have a guide to doing it?

Also, is there an easy way to move my blog from WordPress over to Drupal?

Thanks again.

Yes, it can be done with WordPress... I haven't done it, but it shouldn't be too tough to set up.

Check out this module to migrate from WordPress to Drupal. Note that you'd have to migrate to a D5.x site then upgrade to 6.x, but that's not extremely difficult either.

I'm relatively new to Drupal and this is a very useful post. Thank you. It seemed complicated on first reading but the steps are well laid out and worked on our server. The only difference is that our hosting company does not allow setting virtual hosts to below the public_html directory so the site directories are in public_html while the Drupal codebase is down one level as a directory off the account directory. I was wondering if this makes it less secure than what you were suggesting?

I am also curious why the site1.com directory is created in both the drupal/sites/ directory and the site1/sites directory. I can see how these folders mirror the drupal structure for sites but I really don't understand how this contributes to the functioning and working of this solution.

I was also wondering why symlinks are only needed to point to the drupal/misc and drupal/modules directories and not the other directories in the drupal folder?

I would appreciate any enlightenment you can offer on these questions.

I will now be proceeding to experiment with setting up subdomains using this structure and hope it all works smoothly.

Thanks,

Izzy

Thanks to the wrapper php files, the code is actually executing relative to the drupal directory. This means that your site will work without any symlinks at all. It'll be ugly, since the browser can't see any of the css, js, or image files referenced by the html, but it will be functional.

We use symlinks to expose only those parts of drupal which include public files. Core javascript and images are located in drupal/misc, and modules often provide their own javascript, css or images in drupal/modules. This is why we expose those two directories with symlinks.

Similarly, we don't need to (nor want to) expose the entire drupal/sites/site1.com folder to the public, mostly because it contains the config file for your site. So we expose the subfolders (sites/site1.com/files, modules, themes) with symlinks instead of exposing the entire site config folder.

Justin,

Thanks for the reply.
Now that I have the multi sites working using your symlinks tutorial I realize from reading the other comments that I may be able to move the site1 and site2 directories out of the public_html directory with a symlink for each site directory. So now I am left with a question of aesthetics vs security. By having the site1, site2, etc. folders in public_html it leaves my account directory less cluttered and groups the site folders all in one place. This will leave the wrapper php files, the .htaccess and robots.txt files exposed, but is this really a security risk? Or might it cause other problems?

Secondly, I was reading the previous comments about setting up subdomains and I am a bit confused about how important the naming of the site directories is. For example, if I have two codebases, one for live sites and one for test sites I will have subdomains named test.domain1.com and test.domain2.com so I presumed it would be fine to name the site directories test.domain1 and test.domain2 and now wonder if there is anything wrong with this?

Also if I I have a subdomain named test.domain1.com.project1 can I name the site directory test.domain1.project1 and simply leave out ".com" ?

Thanks again for this very useful tutorial and for taking the time to answer these questions. BTW, I am using Drupal 6.x

Izzy

It is very important how you name the site config folders (the ones under drupal/sites/...) You can name the site folders full of symlinks however you like :)

See here for more info about naming the site config folders.

Justin,

Thanks again. Yes, I have studied the naming of domains and subdomains and how Drupal strips the name as it looks for the directory so I am comfortable with that. Your clarification that the site folder can be named anything is helpful and makes sense and what I was looking for.

Thanks,

Izzy

Post new comment

The content of this field is kept private and will not be shown publicly.
  • You can use Markdown syntax to format and style the text. Also see Markdown Extra for tables, footnotes, and more.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li>
  • Lines and paragraphs break automatically.

More information about formatting options