Skip to end of metadata
Go to start of metadata

Background explanation

Multisites/ Multidomain & Multilevel ACLs

N sites with 1 CiviCRM Database

1. Single / First site installation

Say which would be same as any other normal civicrm installation.

It is not necessary to for the top level site to be multisite aware but if you want it to be then enable multisite by visiting civicrm/admin/setting/preferences/multisite?reset=1.  If you do this you should also grant the associated permission in Drupal: "CiviCRM: administer Multiple Organizations" to your developers or website administrators.

2.a Create a new contact to be the domain contact for the new domain (note steps 2 & 3 can now be done with the MultisiteDomain.create api which is part of the extension)
2.b Insert a new domain record in civicrm db. For example if your new contact is 555
3. Build navigation links for new domain/site

Modify civicrm_codebase/sql/civicrm_navigation.mysql file and specify new domain, e.g



And import this file to your civicrm db

4. Locate sites directory

Setup another site on drupal say This will create sites/ directory in drupal.

5. Locate civicrm settings file for site2

Depending on how you would like to install civicrm for site 2, proceed to one of the following steps:

A): Manual installation for site 2
B): Semi-automatic installation for site 2
C): Multisite for Wordpress
D): Multisite using Drupal's domain access module

A. Manual CiviCRM installation for
  • Copy civicrm settings file from previous site (site1) to the new site (site2).

    Note sites/ is your new settings file which needs to be modified.

  • The sites can share a single instance of the civicrm code in sites/all/modules/ directory if they are using the same CMS.
  • Modify sites/ file to adjust settings like CIVICRM_TEMPLATE_COMPILEDIR, CIVICRM_UF_BASEURL as per new site.
  • Enable the CiviCRM module through Drupal, at Site building -> Modules ( /admin/build/modules ).
B. Auto + Manual CiviCRM installation for
  • Use civicrm installer for installing civicrm for Specify a new civicrm db which can be dropped later.
    Note sites/ is your new settings file which needs to be modified.
  • Adjust CIVICRM_DSN setting to use the civicrm db used by site1. Drop the new civicrm db created in Step B.
  • The sites can share a single instance of the civicrm code in sites/all/modules/ directory.
C. WordPress multi-sites

WordPress multi-sites do not offer  multiple codebases for plugins. There is only one that is shared among all sites. Therefore it is necessary to use the single civicrm.settings.php file and add a conditional statement.

  • You will find the file at /wp-content/plugins/CiviCRM/civicrmsettings.php
  • The existing default code is this:
    echo "you need to configure site : " . home_url();
    define( 'CIVICRM_UF_BASEURL' , home_url() );
  • The code you replace it with could look something like this:

D. Drupal with the Domain Access module

Note: If you're using Drupal with Domain Access, consider installing the Domain Access CiviCRM module if users might be creating new Drupal accounts via CiviCRM profiles.

Similar to Wordpress, with Domain Access module there is only one copy of the codebase, and one copy of civicrm.settings.php.

The easiest is to assign the same domain_id's in Drupal and CiviCRM, then you can just replace this line:

define( 'CIVICRM_DOMAIN_ID'      , 1 );


if (!function_exists('domain_get_domain')) {
// The Domain Access module is not enabled
define('CIVICRM_DOMAIN_ID', 1);
} else {
// Get domain_id from the Drupal setup - Drupal and CiviCRM domain IDs MUST match!
$domain = domain_get_domain();
define('CIVICRM_DOMAIN_ID', $domain['domain_id']);

Otherwise you must replace the above line with a conditional similar to:

//define the per-domain settings here first in case we're running from CLI (e.g. bin/csv/import.php)
if(empty($_SERVER['SERVER_NAME'])) {
  define( 'CIVICRM_DOMAIN_ID', 1 );
  define( 'CIVICRM_UF_BASEURL'      , 'http://example.local/' );
switch ($_SERVER['SERVER_NAME']) {

case 'example.local':
  define( 'CIVICRM_DOMAIN_ID', 1 );
  define( 'CIVICRM_UF_BASEURL'      , 'http://example.local/' );

case 'cdp.example.local' :
  define( 'CIVICRM_DOMAIN_ID', 2 );
  define( 'CIVICRM_UF_BASEURL'      , 'http://cdp.example.local/' );

case 'svp.example.local':
  define( 'CIVICRM_DOMAIN_ID', 3 );
  define( 'CIVICRM_UF_BASEURL'      , 'http://svp.example.local/' );

With either of the above, skip step 6.

6. Register new domain / site

Modify located civicrm.settings.php file (for site2) to change following line -

to reflect the id of inserted domain record in step2. Assuming id is 2 for newly inserted record, the line would change to -

7. Register domain/site group

In multi-org installation, you can configure a group for each multi-site aware domain (not necessarily including the top level domain). When you login to the site and go to "manage groups" screen, you will notice a group with the name as that of domain. System requires you to register this master group responsible for holding sub-groups/contacts. Contacts using the site will be automatically added to the site. You need to set a different group for each site at civicrm/admin/setting/preferences/multisite?reset=1

Note that it is valid not to enable multisite on the top level domain (which is unaware of the subdomains). This improves performance by not creating such a deep hierarchy of groups


8. Associate an organization with the master group

To represent a multi-org hierarchy, an organization could be connected to the master group (one-to-one relationship). Add a record in the civicrm_group_organization table to represent this (or use the MultisiteDomain.create api to create your domain). This record only has value if the multisite extension is enabled.

9. Configure Access Control to restrict users on Site N to contacts in Site N's Site Group

There is a separate extension called multisite that automatically implements CiviCRM access control for multi-site installations, such that normal users on Site N are restricted to contacts in Site N's Site Group. Note that users with permission to view or edit all contacts bypass this access control.