Friday, November 17, 2006

A New Website, Part Four - Drupal Multisite Configuration

This is the fourth part in a series. Earlier this week, in Part One, I described the selection of a hosting services and preparation of the web server. In Part Two, I discuss the reasons I chose Drupal and begin the preparations for installing Drupal 5.0 beta on my new site. Part Three continues that description, wrapping up the software installation. Coming next: configuration and customization.

Multisite Configuration

I decided I needed to attend to the multisite configuration first. As I mentioned, I will be running several sites off the same installation of Drupal. So I need to make sure I have all that sorted out before I try to do any site-specific work.

It's important to notice the logic I have followed here. I have steadily worked from more general things to more specific. I began with the hosting service, which will manage all my accounts, email and websites. Then I attended to the website host's website configuration. Then I installed the sotware that will manage the websites. Now I'm tending to the parts that will manage all three websites.

As usual, the best place to look was in INSTALL.txt and I found there a section on installing multi-sites. Basically, each site gets its own configuration file, settings.php, and this file is located in a sites subdirectory names after the URL of the site it describes. A 'default' settings file takes over if any settings file is missing (and if you have only one site, the default settings.php file is already set up, so you can ignore this). So I will have, for example:


To set this up, I used my gftp program to create the '' subdirectory under the 'sites' directory. Then I copied 'default/settings.php' into ''.

Next, I saved a copy of the file on my home computer, then I opened it up with a text editor (on Linux, a program called gedit, the default editor for Ubuntu; on Windows I use a text editor called Notetab (which I use because it can save files in 'unix' format, not one of the messy Microsoft formats, essential if you are writing software).

If you are going to do any sort of work on the web, you need to learn to read script files. PHP is a funny language, in that bits of web page HTML and bits of PHP are mixed up in the same file (like I said, PHP is messy). The way to think of it is this: every PHP page is a web page, and inside the web page there is some PHP code. PHP code is embedded in the web page, just like an image or a link or some Javascript code.

The beginning of a segment of PHP always looks like this: <?php

And the end of a segment of PHP looks like this: ?>

In Drupal, you'll hardly ever see the end of a PHP statement, because the page is made up entirely of PHP coding.

Inside the PHP, you have two types of text: code, which does the actual processing, and comments, which provide advice and instruction to anyone editing the page. The comments are enclosed between '/*' and '*/'. So the trick to working with a PHP page is to read the comments and then edit the code.

It is worth noting that lines that begin with '#' are also comments. This is an import from Perl (which only uses the '#' designation). Like I said, spaghetti code. Usually, people use the '#' to block lines of code they are working on but don't want the program to run.

So anyhow, I open and read the 'settings.php' file. There's quite a bit of commentary telling me about the sites subdirectory and how to specify special characters in the username and password. Then I see my first line of PHP code:

$db_url = 'mysql://xxxx:yyyy@localhost/drupal';

I have replaced the actual values. 'xxxx' is the name of the database user, while 'yyyy' is the database user's password. 'localhost' is the server the database is running on. And 'drupal' is the name of the database. Basically, we are handing the keys of the database to Drupal with this statement.

What's neat and important about this is that I can set up a different database for each of my sites. In fact, I want to do this, because I'll want to use different themes and have different data for each of my sites. So what I do next is I create a new database, which I'll call 'downes'. And I'll do that in the same way I created the first database, with the CSoft panel.

I keep reading through the file. I see I can create a prefix for all database names. I don't need that (if you are using cpanel, though, like I was on JaguarPC, you need that). I see I can create a default domain name - so, for example, if somebody typed '' I could force them into ''. This is useful for making sure images and things load properly. But I don't need it now, so I leave it. Then there's a bunch of 'ini_set' statements, covering things like 'magic quotes' (that awful Microsoft character) and cookies. The defaults are good enough, so I leave them aside too. And that's the end of my 'settings.php' file.

Good, then. I save the file, and then upload it into the /www/drupal/sites/' directory. Then I open a web browser and point it to ''. This is important. Always test things when you change them. In this case it's especially important, because we are not pointing to an empty database. Drupal is going to have to install all the database tables. And I'm going to have to create a new administrator, just for ''.

What I get instead of the installation routine I expected is an error:

Fatal error: Call to undefined function: block_list() in /home/downes/www/drupal/includes/ on line 966

Since the only change I've made is to the database, I figure it's because the new database is absolutely empty - Drupal hasn't done anything to fill it with the necessary tables and data. So, what to do? I could just return to the original database. But then I'd have all my sites running off the same database - it would be like they're all the same site. There's a certain appeal to that, but I'd rather keep things separate.

No, what I am going to have to do is to set things up manually. So what I'll do is copy the original 'drupal' database into the new 'downes' database. Now I have my ideas about how to do this, but I decide to play it safe and search Google for 'copy one database to another mysql'. But nothing really relevant comes up (and why are all those 'MS SQL' pages in the results - is Microsoft link-spamming Google?).

On the whole, this is rather annoying.

OK, what I'm going to need to do is to be able to look at the databases directly to see what's going on. After all, I'm just assuming Drupal left the new database empty. This means I will need to install a program called phpMyAdmin. This is a wonderful utility that will let me look at my databases directly.


I download phpMyAdmin-2.9.1-english.tar.gz from the PHP site to my home computer, then using gftp, I upload it to the www directory on my website. I then extract it the way I extracted Drupal, with the 'tar -xzf phpMyAdmin-2.9.1-english.tar.gz' command. This puts it into a director with a really ugly name, 'www/phpMyAdmin-2.9.1-english.tar.gz'. So I use the command 'mv phpMyAdmin-2.9.1-english.tar.gz phpMyAdmin' to clean up the name. Then I type 'cd phpMyAdmin' and I'm in the directory. There is an INSTALL.txt file, which refers me to another file, which tells me how to set up phpMyAdmin.

The main thing is, just like Drupal, I need to give phpMyAdmin the keys to the database. I have to tell it where to find it and how to get in. "Traditionally, users have hand-edited a copy of, but now a wizard-style setup script is provided for those who prefer a graphical installation." Well, I haven't tried the wizard before, so that's what I'll use.

I need to access the script with my browser. It's sitting in www/phpMyAdmin, but all requests to my website go to Drupal. So I need to give the site a way of going to phpMyAdmin. Since I only have one domain name to work with, I decide to route requests to the IP to the phpMyAdmin directory. I type 'cd ..' to get back into the 'www' directory. Then I first remove, then rewrite, the symbolic link I created yesterday.

ln -s phpMyAdmin

So now, if I point my browser to, it should take me to the phpMyAdmin home page, and hence, to the wizard. So I try that.

It tells me I have a connection error (not surprising) and gives me a link to the setup script. I follow the link and it tells me I need to create a directory. Huh? Oh, I guess I should have real all the instructions: "First you must manually create a folder config in the phpMyAdmin directory." It then gives me the Linux commands:
   cd phpMyAdmin
mkdir config # create directory for saving
chmod o+rw config # give it world writable permissions
Notice the comments, prefaced by '#'. You don't have to type those.

Notice the 'chmod' command. This sets the permissions so that the whole world can't read this directory. You wouldn't believe how many people leave their phpMyAdmin setup files open in plain view for anyone to read them (just Google site:* to find them.

OK, so I make the directory and then reload my setup page. It likes this much more (it is still complaining about my now using a secure server, but this is just a personal website, not anything secret or commercial). So I click 'servers: Add' and see a form with 'localhost' already entered. Perfect. I enter the database username and password, as well as a new username and password for access to phpMyAdmin.

It didn't work. Why not? I check the 'config' directory. There is a file in there, but it's empty. Also, phpMyAdmin sais "You did not set up a phpMyAdmin database". OK, I'll go back to the CSoft panel, create a phpMyAdmin database, and see if that helps. I create a new database called 'phpMyAdmin' (I really have no imagination when it comes to database names) and grant access to the database user. Then back to the phpMyAdmin wizard. I fill in all the information again, and this time include the name of the phpMyAdmin database.

OK, it likes that, reminding me, " Remember to protect your installation while using config authentication method!" Let's see if it works. I open the browser to, and...

Failure. "#1045 - Access denied for user 'root'@'localhost' (using password: NO) "
This is the same error as before, and it's not even trying to use the username and password I gave it. Why not? I check the config directory again. It has simply not written to the config file. Can't say why - maybe it has to do with permissions, though everything seems OK.

OK then. Forget the stupid wizard that doesn't work. I'll create the file manually. Back to the instructions I go.

Oh for gawds sake. I read this: "Note that changes are not saved to disk until explicitly choose Save from the Configuration area of the screen." So I go back to the setup screen, input the values again, hit 'Add', and then (searching around a bit, because it's in the middle of a bunch of buttons) click 'Save'. This does create a config file. Now I'll go back and try to access my database.

And.. failure. Again. It is as though it simply cannot read the file. Why not?

Maybe it's the config directory permissions. The directory is wide open right now. Some servers are set up to prevent access when the premissions are too loose (yeah, that's backwards, but I've seen it). I tighten them a little (you highlight the file or directory name, right-click, then choose 'chmod'). Nope, that doesn't work.

I mess around with it again. Finally, after I hit 'Save' yet again, I notice this: "Configuration saved to file config/ in phpMyAdmin top level directory, copy it to top level one and delete directory config to use it."

Oh for gawds sake. Why on Earth would it save it to one directory and have me copy it to another directory?

Using the terminal, I go into the phpMyAdmin directory and type:

cp config/

Now we'll try again, and...

Success! But now the whole world can access my database. So I think I'll use a different access method. So using the backspace key (there's no link back to setup) I change the 'authentication' to 'cookie' and save it again. Then I copy the config file again, using the same command. Then I test it. Good, now it wants a user name and password.

OK good. Now let's get rid of that config directory:

cd config
rm *
cd ..
rmdir config

I test to see whether people can read They can't. Good. I'm set up with phpMyAdmin.

Multisite Configuration - Reprise

I can see from the home screen (because it says how many tables each database contains) that my suspicions were correct. The 'drupal' database has 40 tables. The new 'downes' database has none. I'm going to gave to copy all the tables from 'drupal' to 'downes' for this to work. What an annoyance!

Um... hmm. It seems I have some extra databases in my database - looks like employee records for some company in Poland. I'll have to send a note to the server administrator; I shouldn't be able to see these. And by the same token, I don't want some stranger in Poland able to see my databases.

OK, now to copy the database. In phpMyAdmin, I click on the 'operations' tab. Then, under 'copy database' I type 'downes' in the field, and uncheck 'Create Database' (since I've already created it). I click the 'Go' button and wait for phpMyAdmin to report back (this may take a moment)... Success! " Database drupal has been copied to downes".

Now - did it work? I point my browser to again. Yes! I have my admin screen. I even have the administrator account that I created for 'drupal'. It's an exact clone of the database. Perhaps too exact - I would have wanted to create a different administrator account. But this will do for now - especially since the people at Drupal didn't even bother to put this in.

It now occurs to me - maybe there's some sort of way in Drupal to have done all this. I'll try a Google search. Oh - I see. According to this site "you'll need a distinct prefix for your table names". OK, you could do it that way then, creating versions of the different tables in the same database. But you're still creating these tables manually. Ugly. This page recommends that you do as I did - copy the database (and you know, I really hate it when people write stuff like "Read the 'Multisite configuration' part in your INSTALL.txt. It's all explained there." It's not all in there - that's why people are asking!

Anyhow. Multisite configuration are go. Time for lunch.


  1. Also, note that you can create "themes" and "modules" directories within each site's directory, and have themes and/or modules available only to that particular site. comes in handy if you want to add functionality to one site without complicating others, or need to run incompatible modules on different sites.

  2. Alternatively, you could have just pointed your browser to . This will populate the database you connected to in your settings.php file.

  3. Perhaps, garrido, you didn't notice where I wrote:

    What I get instead of the installation routine I expected is an error:

    Fatal error: Call to undefined function: block_list() in /home/downes/www/drupal/includes/ on line 966

  4. Thanks for laying down your phpmyadmin thoughts. I read to "Note that changes are not saved to disk until explicitly choose Save from the Configuration area of the screen." and realised that is something I hadn't done. Tried again, clicked Save, brilliant! Thanks.


Your comments will be moderated. Sorry, but it's not a nice world out there.