Photo of several old Airstream trailers buried end-up in a field

Create and maintain a family of Drupal sites using shared configuration instead of install profiles.

Several of our clients manage multiple small sites for independent centers or groups within their organization. These sites often share an information architecture and key features like SSO integration and editorial workflows. They differ mainly in their content, and who manages the content for each site. They  are visually distinguished by logo and color, but share much of their page layout and components, meaning they can share a design system and theme as long as it provides a few options.

This group of sites can be run as Drupal "multisites", where multiple Drupal installations run on the same Drupal codebase and hosting infrastructure. A typical approach for setting up these sites would be either to install and configure each independently, using the same underlying code but re-creating the content types, taxonomies, and content management workflows for each -- or, to create one site and clone it. What this does is create multiple distinct Drupal sites that need to be updated independently when the content types or module configuration needs to evolve.

At this point you could consider building a Drupal "install profile", which lets you create identical new sites. However, the process for maintaining shared configuration after installation is to write update hooks, a tedious process compared to Drupal's config management.

Sharing base configuration

The approach we took instead was to share a base set of configuration -- the bulk of the Drupal config -- between all of the sites. This means that sites start from a complete set of features, including content type, taxonomy, and menu configuration as well as modules like SSO and workflow. A limited number of configuration items -- like the site name and 404 page, the logo and color theme settings, and others as needed -- are split out into site-specific config folders.

Not only do sites start from a complete shared set of features, but as features are added to the main configuration, each of the sites receive the new functionality at the same time.

Consider a case where you want to install a new module across all of the sites. For multisites set up with an install profile and independent configuration, you would need to enable and configure the module on each site independently. This would require careful attention to ensure the changes were applied on each of the sites, and verifying that you made exactly the same configuration decisions on each. When you discover that an option needs to be tweaked, you go back into each site and update it.

For multisites set up with shared config, you can install and configure the module once. The shared config will propagate the changes to each of the multisites. As you tune the module configuration, these changes too will go out to the multisites using straightforward config management processes -- no update hooks required.

Step by step

Here's how this works:

Set up

  1. Start by installing and configuring the first site
    1. Export the configuration to what will be the shared config directory
  2. Install Config Ignore, and configure it to at least ignore “system.site” (and probably “blocks.*”). Any other settings that vary across sites (ex: theme settings, colors, etc.) will also need to be added here.
    1. Configuration that is ignored will still be used when a new site is installed -- they act as "base config" -- but won't be imported again after installation
    2. If there's configuration that shouldn't be used as base configuration (often relevant for blocks), there are two options for making the Config Ignore workflow cleaner:
      1. Config Export Ignore will prevent certain configuration objects from being exported
      2. OR add a .gitignore in your config directory to exclude the files
  3. Install Config Split if there are modules that only need to be enabled on certain sites; when using Config Split, each site or group of sites will need their own split configuration directory.
  4. Now your config is ready for re-use.

Adding more sites

  1. Set up the scaffolding for a new multisite using the normal multisite set up process
  2. Make sure each multisite uses the shared config directory that you've created
    1. See Drupal's documentation on changing the storage location of the sync directory
  3. Install the new site from config when running install.php
    1. Using the web interface, select "install from config"
    2. OR using the command line, run drush si --uri=MULTISITE_URI --existing-config

Updating sites

  1. To make a change across all sites:
    1. Edit any site
    2. Export configuration -- this will update config in the shared config directory
    3. Check the changes into your repository
    4. Import config on the other sites
  2. To make a change that will only affect one site (this change will live in the destination/prod environment only)
    1. Make the change on the one site, locally
    2. Add the config to Config Ignore and export the configuration
      1. Both the Config Ignore settings and the changed config will be exported!
      2. Commit the changes to Config Ignore, but NOT the config file that you're ignoring
      3. You may want to add the specific files to the .gitignore so they don't accidentally get checked in and used as base configuration on new sites
      4. Note that the Config Ignore rule won't prevent the new configuration from being imported unless it is present BEFORE the new config is present
    3. Deploy the Config Ignore changes
    4. Make the desired change on the prod site
    5. If you're ignoring an entire class of config (like all block configuration), you only need to do this the first time you set up the Ignore
  3. To update core or modules across all sites
    1. Managing updates across multisites follows the standard process -- update the shared codebase and then run the update hooks on each site individually
    2. Config that is changed by a module update only needs to be exported once

Making Multisites Easy

There's always a balancing act between the specific needs of one website among many, and the stability and maintainability of a single codebase and feature set. Creating a family of multisites is a great way to isolate editorial responsibilities, allowing divisions or centers independent control of their content and navigation; sharing the code AND configuration between these sites allows sustainable maintenance and iterative feature rollouts.

Airstream Ranch by Carlyle Ellis Photography/Human Quotient, licensed under CC BY-NC-ND 2.0.

Drupal Site Building