Drupal 7 and sites.php

Monday, January 9, 2012 - 19:05

You might have seen the example.sites.php file on the sites directory when setting up your Drupal installation. This is your new friend when setting up a multisite installation on Drupal.

The the g' old way of doing this was to create symlinks for each of the site into the sites directory. Like this:

Multisite installation with aliases

This is a typical installation of a multisite with a development, staging and live site for each site:

  • Local development sites for developers (.dev domains)
  • Staging server sites for staging (stagingsite1/2/3.mearra.com)
  • Live server sites for, yeah, live sites (livesite1/2/3.mearra.com)

As you can see, this doesn't look nice and has it's flaws. For example, let's take PhpStorm IDE: the lovely editor is automatically assuming that you have 12 (twelve!) different sites directories that needs the indexing. That goes without saying, the indexing might take a lot of a time.

But the sites.php is the cure for this. You can just copy the example.sites.php file into sites.php or create a new file. Then add something like this in it:

$sites = array(
 // Development sites
 'devsite1.dev' => 'site1',
 'devsite3.dev' => 'site2',
 'devsite3.dev' => 'site3',
 // Staging sites
 'stagingsite1.mearra.com' => 'site1',
 'stagingsite2.mearra.com' => 'site2',
 'stagingsite3.mearra.com' => 'site3',
 // Live sites
 'livesite1.mearra.com' => 'site1',
 'livesite2.mearra.com' => 'site2',
 'livesite3.mearra.com' => 'site3',

Now your sites directory looks way more cleaner and you don't have to worry about any of the common problems caused by symlinks.

Multisite installation with sites.php

And you're all set!


Package icon sites.php__1.zip


But how does this relate to the settings.php? We use a different database for dev, staffing and production. Can this be handled in sites.php as well?

I simply use a switch statement to include all the db credentials in settings.php Also quite handy for other settings (e.g. caching always off on dev and always on on prod)

That sounds pretty cool. Wanna share any examples with multiple different settings between sites on settings.php? I'd love to see.

I'm also interested if you could show some example of your setup.

It simply looks like this (D6, but you get the point for a D7 site). I normally store this in a separate file (not in settings,php) and refer to it from within settings.php. This way I can even store the credentials outside the document root, making it somewhat safer in case the webserver fails to protect my files. It's also convenient to switch off caching / aggregating in the dev or test environments, to disable analytics in non-production, and so on. I have not tried yet the multisite config, but I don't see any reasons why that shouldn't work.

switch($_SERVER['HTTP_HOST']) {
// development
case 'sitename.local':
$db_url = 'mysql://:@/';
$db_prefix = '';
$conf['environment_indicator_text'] = 'DEVELOPMENT SERVER';
$conf['environment_indicator_color'] = 'dark-red';
$conf['environment_indicator_enabled'] = TRUE;

// Test
case 'test.domain.tld':
$db_url = 'mysql://:@/';
$conf['environment_indicator_text'] = 'TEST SERVER';
$conf['environment_indicator_color'] = 'orange';
$conf['environment_indicator_enabled'] = TRUE;

// Accept
case 'accept.domain.tld':
$db_url = 'mysql://:@/';
$db_prefix = '';
$conf['environment_indicator_text'] = 'ACCEPT SERVER';
$conf['environment_indicator_color'] = 'green';
$conf['environment_indicator_enabled'] = TRUE;
// Production
case 'domain.tld':
case 'www.domain.tld':
$db_url = 'mysql://:@/';
$db_prefix = '';
$conf['environment_indicator_text'] = '';
$conf['environment_indicator_color'] = 'transparent';
$conf['environment_indicator_enabled'] = FALSE;

Hi Sampo,

I have my sites array properly setup and working.
But when I login I can't get to the admin section.
Drupal 7 keeps telling me 'Access denied'.
This is only when I use the alias.

Can you help me?

Thanks in advance.

Hi Fred,

Hard to say without more info about the setup.

What kind of sites.php setup are you having on your machine?
Have you cleared the cache on your Drupal installation after setting up the sites.php?
Do you have some site-specific configurations on your settings.php (such as $cookie_domain)?

Hi Sampo,

Yes I have a cookie_domain set.
The cookie_domain is set to the original site folder.

$cookie_domain = '.subsite1';

Should I add the alias or change it to the alias?
Will other modules still work, for example CKEditor?


That might be the problem.

As usual, different sites on different servers are normally using their own settings.php files. That's just because you might (and should) use different MySQL passwords, cookie domains and such on different servers.

If you are using the same settings.php for every site (or are just using modified version or local machine, or something related), you could do the neat trick by Marcel above:

Could this fix your problem?

I'm using a different settings.php file for the default site and each subsite.
So every site has it's own settings.php file.

I just not sure which 'url' I should use for the cookie_domain, the original subsite/folder name or the alias. Or that I should add the alias.

$cookie_domain should be the one that you are accessing the site from (so not the directory name). Same goes for all subsites and environments.

Thank you Sampo.
You're a lifesaver.