We are setting up Drupal in a University environment. This means we cannot just rely on everyone playing nice.
As such, our web servers are set up so that different organization's sites run as separate users. On our legacy systems, this is done with a customized version of cgiwrap. For our new Drupal system, we are using suphp. And while we could just turn on suphp, hand out the Drupal source, and tell user to have fun, we would like to instead hand out running Drupal installs ready for them to customize. But if we are going to be supporting several dozen subsites, we would prefer to have one set of code to update, and to be able to offer "blessed" modules as globally available, including for some modules (e.g. LDAP) pre-installed and configured before we turn over the site.
That would point us in the direction of multi-site. But standard multi-site Drupal just uses symlinks to the Drupal root for subsites, which means all the php code is owned by one user, so that would not work with suphp, which runs php files as the file owner.
This is our attempt to have our cake, and eat it too. It seems to work in our test environment, but we are not Drupal experts; we only started learning Drupal last month. If you can pick flaws in this, please do! We'd rather learn about problems now than later.
Our environment is Drupal 7, apache2, and suphp running on Linux. If you are running something else, your mileage may vary. I assume you already have suphp working. I also assume you are familiar with doing a basic Drupal install. For this example, our base site will be www.oursite.edu. At our school, we use per-organization web users for running an organization's subsite. These are sometimes referred to as w3* users, because our convention is the usernames all start with "w3".
1. Install the Drupal source code someplace outside of the Apache webroot. In this example, I use /usr/local/drupal-7.8 to hold the Drupal 7.8 code.
cd /usr/local tar zxvf /tmp/drupal-7.8.tar.gz chown -R nobody:nogroup drupal-7.8
2. Create a symlink /usr/local/drupal-current pointing to the current version. This will save you effort when you need to upgrade to a new version.
ln -s /usr/local/drupal-7.8 /usr/local/drupal-current
3. You are now ready to create a multi-site subsite under the web Document Root (/var/www by default on Debian or Ubuntu, /var/www/html on RedHat). For this example, I am going to set up a Drupal site for the Paperclip Collectors Club, which will live at http://www.oursite.edu/paperclips, and run as the user and group w3paperclips. First you need to create the directories and symlinks the site will need.
cd /var/www mkdir paperclips cd paperclips ln -s /usr/local/drupal-current/includes includes ln -s /usr/local/drupal-current/misc includes ln -s /usr/local/drupal-current/modules modules ln -s /usr/local/drupal-current/profiles profiles ln -s /usr/local/drupal-current/scripts scripts ln -s /usr/local/drupal-current/themes themes ln -s /usr/local/drupal-current/.htaccess .htaccess mkdir sites mkdir sites/all mkdir sites/all/modules mkdir sites/all/themes mkdir sites/default
4. Now you need to put special "stub" versions of the php files in place.
echo "<?php include('/usr/local/drupal-current/authorize.php'); ?>" >authorize.php echo "<?php include('/usr/local/drupal-current/cron.php'); ?>" >cron.php echo "<?php include('/usr/local/drupal-current/index.php'); ?>" >index.php echo "<?php include('/usr/local/drupal-current/install.php'); ?>" >install.php echo "<?php include('/usr/local/drupal-current/update.php'); ?>" >update.php echo "<?php include('/usr/local/drupal-current/xmlrpc.php'); ?>" >xmlrpc.php
5. Finally change the ownership of the whole subsite to the user you want suphp to run the site as.
cd /var/www chown -R w3paperclips:w3paperclips paperclips
6. At this point, assuming you have the database for the site set up and ready to go, you can go to http://www.oursite.edu/paperclips/install.php and do a Drupal install.
7. Once you finish the subsite install, it is time to add a few more tweaks.
cd /var/www/paperclips/sites mkdir www.oursite.edu cd www.oursite.edu mkdir files ln -s /usr/local/drupal-current/sites/all/modules modules ln -s /usr/local/drupal-current/sites/all/themes themes ln -s ../default/settings.php settings.php cd .. chown -R w3paperclips:w3paperclips www.oursite.edu
By doing this step, you make any modules or themes installed in /usr/local/drupal-current/sites/all available to this subsite. Note that this does mean that if you have module installed in the /usr/local/drupal-current/sites/all (or "global") area, your subsite administrator will not be able to install a module of the same name. Administrators will be able to install non-conflicting modules and themes through the web interface locally (only available to their subsite), which will end up in their subsite's sites/all directory.
8. Now that you have made one site, you can make others in a similar manner (or, if you are like us, work on scripting the above steps to automate site creation). But what happens when a new version of Drupal is released? Say we want to move to 7.9?
First we install the source in /usr/local/drupal-7.9, and then we can test it out on one of our test subsites, by changing all the links/includes from /usr/local/drupal-current to /usr/local/drupal-7.9 and running update.php. After we are satisfied it works, and making sure all our backups are in place, we put each subsite offline, change the one symlink for /usr/local/drupal-current to point at /usr/local/drupal-7.9, run each site's update.php, and them put them all back online. After that, all the of the subsites will be running version 7.9.
This also has the advantage that if you have one or two subsites that (for whatever reason) cannot move to the new version, you can "pin" them to a specific version of Drupal by changing their .php stub files and symlinks to point at that particular version instead of /usr/local/drupal-current.
That is all I have for now. We would appreciate questions, comments and feedback. If you see a problem with our set up, please let us know!