Multisite Moodle, Part 1

For about a year now I have been trying to figure out how to simplify the management of the Moodle sites that we host. As of now, to run nine sites takes nine separate installs of the Moodle software. This seems ridiculous since there is not any site-specific info stored inside Moodle’s installation directory. And now for the good news… I have figured out how to run multiple Moodle sites out of a single Moodle installation by utilizing symlinks and a modified config.php. Click the Read more link to see how I have done this.

 
So, let’s dive into some of the deep details of how I have setup a multisite Moodle.   Before diving in though I need to explain how I have setup the installation so that you will understand why things are done the way they are.  

 
To enable access the Moodle site at http://www.wgretc.org/elearning/moodle1 I created a folder in the web root of http://www.wgretc.org called elearning.  Inside of there I created a symlink called moodle1 that points to /usr/share/moodle.  Utilizing symlinks allows me to accomplish two things:

  1. Have Moodle installed outside of my web root.
  2. Reference one Moodle install that is not directly web-accessible by many "sites" such as moodle1 and moodle2.

Once I created the database moodle-moodle1, got the moodle1 symlink in place, and the moodle1 data directory in place I navigated to http://www.wgretc.org/elearning/moodle1 and the install script started automatically.  I proceeded through it as normal.  Once it finished I ensured the site was functioning as it should.
 
The next part is where it got tricky.  Since there is only one config.php in the Moodle root I had to modify it to use variables instead of static paths.  The result is a config.php that uses the database and data directory that correspond to the web address being accessed.  Here is the config.php that I created:
 
 
<?php /// Moodle Configuration File
unset($orig_page);
unset($pieces);
unset($CFG);
 
$orig_page  = $_SERVER["REQUEST_URI"];
$pieces = explode('/', $orig_page, 4);
 
$CFG->dbtype    = 'mysql';
$CFG->dbhost    = 'localhost';
$CFG->dbname    = 'moodle-'.$pieces[2];
$CFG->dbuser    = 'mUser';
$CFG->dbpass    = 'password';
$CFG->dbpersist =  false;
$CFG->prefix    = 'mdl_';
 
$CFG->wwwroot   = 'http://'.$_SERVER["HTTP_HOST"].$pieces[0].'/'.$pieces[1].'/'.$pieces[2];
$CFG->dirroot   = '/usr/share/moodle';
$CFG->dataroot  = '/var/lib/moodle_data/'.$pieces[2];
$CFG->admin     = 'admin';
 
$CFG->directorypermissions = 00777;  // try 02777 on a server in Safe Mode
 
require_once("$CFG->dirroot/lib/setup.php");
// MAKE SURE WHEN YOU EDIT THIS FILE THAT THERE ARE NO SPACES, BLANK LINES,
// RETURNS, OR ANYTHING ELSE AFTER THE TWO CHARACTERS ON THE NEXT LINE.
?>
 
As you can see, there are some odd looking lines in here now so let’s break it down.  We start out by clearing the contents of the variables:
unset($orig_page);
unset($pieces);
unset($CFG);
 
We then make two new variables:
$orig_page  = $_SERVER["REQUEST_URI"];
$pieces = explode('/', $orig_page, 4);
The first one stores whatever is in your address bar after the www.wgretc.org.  The second takes and uses the explode command to break the address at the /'s and stores the results in an array.  The last part of the second line says that everything after moodle1 is stored as a single string since we do not care about that part.  Putting this all together, the web address www.wgretc.org/elearning/moodle1/admin/replace.php is stored in an array as
 0:  
 1: elearning
 2: moodle1
 3: admin/replace.php
 
As you can see, there is nothing stored in the position 0 of the array... this is because we did not pass in the www.wgretc.org part so there is not anything before the / that comes after .org.
 
Next comes
$CFG->dbname    = 'moodle-'.$pieces[2];
$CFG->dataroot  = '/var/lib/moodle_data/'.$pieces[2];
This looks at what is in position 2 of the array, in this case moodle1, and inserts it in the database name and the dataroot path.
 
Lastly, we have the most complicated looking line:
$CFG->wwwroot = 'http://'.$_SERVER["HTTP_HOST"].'/'.$pieces[1].'/'.$pieces[2];
This strange combination of things pieces together the base web address of the Moodle site by doing the following (to save space, I am guessing you can figure out the parts that are repetitive):

  • http://      --enough said.
  • .       --concatenate symbol in PHP.
  • $_SERVER["HTTP_HOST"]   --this pulls the www.wgretc.org part of your web address
  • '/'       --adds a / to the address
  • $pieces[1]     --gets the elearning part from position 1 in the array.
  • $pieces[2]     --gets the moodle1 part from position 2 in the array.

 
There is one more thing you need to do.  Once the site is up, go to Administration --> Server --> Session Handling and check the top box to use the database for session information plus enter the site name (moodle1 in this case) in the box for cookie prefix.  These ensure your browser does not get confused about what site you are visiting.
 
I am running two sites this way now and about to roll out a template site so that I can start creating the other needed sites.  I will post info on how to make the template site as a separate entry.