Setting Up Moodle in Multi User Mode

Setting Up Moodle in Multi User Mode

by Jez H -
Number of replies: 3

Someone just messaged me asking how to set up multiple Moodles from a single code base, rather than reply on PM I thought I would post it here.

The idea is to run more than one Moodle instance from a single codebase. We do this so that different faculties can be configured differently. It also means individual Moodle instances are smaller, backups are segmented so its easier to restore a single faculty should dissaster strike.

There are some caveats to doing this:

1) If your organisational structure changes you cannot simply rename / move categories as courses exist in different moodles.

2) Users accessing more than one system essentially end up with separate accounts on each of them.

That is not generally an issue for us as both staff and students tend to work only in their faculty instance.

We also have SSO implemented so moving between systems is seamless and if you hit a "new" moodle account creation is automatic.

To implement this you need toparse the URL for (in our case) the faculty name / shortcode.

We used to do this with subdomains like:

facultyone.ourdomain.ac.uk

facultytwo.ourdomain.ac.uk

But later switched to:

ourdomain.ac.uk/ (a central Moodle that sits above the others for generic courses / staff training etc)

ourdomain.ac.uk/fac1 (faculty moodle)

ourdomain.ac.uk/fac2 (faculty moodle)

Clearly you need to make sure you do not use existing Moodle urls like:

ourdomain.ac.uk/course

ourdomain.ac.uk/my (my moodle page)

It will be the second method I explain below.

The only file you need to edit is config.php

First we set default values as normal in config.php, these are set with our top level instance which sits on the root domain:

$CFG->wwwroot  = 'ourdomain.ac.uk';
$CFG->dataroot  = '/moodledata';
$CFG->dbname = 'default';

Then we grab the requested URL and split it out based on "/"

$url_array=explode("/",$_SERVER['REQUEST_URI']);

Then we grab the second segment (zero being the first):

$faculty_code = $url_array[1];

(If you were using sub domains you would explode on "." and extract the sub domain rather than a URL segment)

so where the url is ourdomain.com/fac1/

$faculty_code would be "fac1"

Next we define an array of allowed shortcodes to ensure we only handle the correct codes. We do this in $CFG as we re-use these values in themes, custom navigation and jump URLs for MNET:

$CFG->facs = array('fac1', 'fac2', 'fac3');

Then we test against this array and if we find a match set parameters accordingly:

foreach ($CFG->facs as $fac){
    if($faculty_code == $fac)
    {        
        $CFG->wwwroot  = $CFG->wwwroot . "/".$faculty_code;
        $CFG->dataroot  = '/moodledatafor' . $faculty_code;
        $CFG->dbname = 'databasefor' . $faculty_code;      
   }
}

(You could test with "in_array()" before entering the above)

So if someone hits ourdomain.ac.uk/my they hit my moodle on our central instance using the default values.

If they hit one of the /fac1/ short codes we load a different database and moodledata directory.

If you are using subdomains things are a little different as you dont have to worry so much about people hitting erroneous urls as you can only access a subdomain which has been added in the webserver, though it would still be a good idea to limit them in an array if you are able to.

Once upon a time we used to have only one database and set the prefix i.e. change mdl_ to fac1_ etc, that is not a good idea as Moodle's database is pretty substantial, you really need to use separate DB's.

I hope that's useful some of you smile

Average of ratings: Useful (5)
In reply to Jez H

Re: Setting Up Moodle in Multi User Mode

by Luis de Vasconcelos -

Interesting...

Do you have a separate database for each "instance"?

And how do you handle upgrades?


In reply to Jez H

Re: Setting Up Moodle in Multi User Mode

by Ron Meske -
Picture of Particularly helpful Moodlers

Hello Jez.

Looks like you posted your solution a while ago and I just came across it.  This type of question does seem to be asked quite often, so thank you for posting your solution.  It does look easy to implement, especially compared to some I have seen.

If you do happen to come across my post, I do have a few questions:

  1. Was there a particular reason you switched from using subdomains to using folders?
  2. Did you do anything different to handle repositories and caching beyond using different moodledata folders?
  3. Did you look at performance to see if using one install of moodle impacted performance in a positive or negative way? 
  4. Besides the moodle database being quite large in terms of tables, did you see any performance issues with using one, or a performance improvement when you split it into multiple databases?
The one downside I see to your solution is that all instances will be running the same version of moodle.  Not necessarily a bad thing, but it does mean all instances will have to be tested at the time of the update to ensure it does not break any of them.

In summary for those that currently run multiple moodle instances and have considered something of this nature, the advantages are:

  • Less disk space  and potential of faster access when drive access is cached, for example, a raid system
  • One code base of moodle to keep current with security patches and updates
  • You can easily use different themes for each instance
  • Each instance has it's own database which keeps data separated, which can be particularly important to corporate clients.  It also means there is the ability to using different database servers if required
  •  This simplifies the backup and restore process for disaster recovery.  
The main disadvantage is the moodle upgrade process, as there is only one instance of the moodle code.  This means you will have to upgrade all instances at the same time and during that process all sites will be unavailable until its upgrade as been completed.  After making your backups you would:
  • Log into each instance and place into maintenance mode
  • Update the moodle code base
  • log into each instance to perform the upgrade
  • Test each instance to ensure nothing broke
  • Turn off maintenance mode for each instance