I spent some time in late 2020 blogging about some of the planning you need to do if you want to go with Drupal multisite for your platform. That’s really useful background information, but let’s take it a step farther: what if you want to experiment with Drupal 9 multisite? What if you want to take it for a whirl? Unfortunately it’s something you can just “do.” It takes a bit of effort to get everything up and running. So this post should help!
I’ll be using the following tools in this tutorial:
Note: as of BLT 12 you may need to also add the https://github.com/acquia/blt-multisite plugin if you get any errors about the Multisite recipe not existing.
If you want to see the end result and/or follow along, I have created a public facing Github repository that you can look at for an example. See https://github.com/mikemadison13/multisite.
Before I jump in, a shoutout to my colleague Beverly Lanning who has extensively documented this process over on Acquia’s Knowledge Base (and this material was very helpful as I worked through this process last week).
I also want to give a general disclaimer that if you are planning on running a multisite platform with “hundreds or thousands” of sites, setting up a local multisite for all of those sites might not be advised. Obviously hosting platforms can and do support multisite platforms of this size and scale but trying to manage that many locally might be a bit challenging.
Initial Project Setup
I tend to use acquia/drupal-recommended-project over drupal/recommended-project. Either will work, but the Acquia version comes pre-baked with some of the BLT stuff in it. So I’d suggest starting there. Here’s the command I ran to instantiate the project locally.
composer create-project --no-interaction acquia/drupal-recommended-project multisite
Then, I added the BLT Drupal VM plugin.
composer require acquia/blt-drupal-vm
A brief note: I have been doing a lot with Lando recently! But I am working with a customer who is already using Drupal VM, so I did this work there. If there’s interest, I can post a similar tutorial for doing this with Lando in the future.
The next thing I did was configure my Drupal VM but I did not provision it. BLT provides a recipe for this! I just did:
blt recipes:drupalvm:init
Again, when BLT asked me if I wanted to provision the VM I did not.
The next step is to start tweaking the VM config. Here are a few things I did…
Changed the PHP version to 7.4 (vs. the 7.3 that ships with BLT out of the box).
Updated XDebug version. The stock version (as of 2/22/2021) in the BLT VM config file is 2.7.1 which isn’t compatible with PHP 7.4.1 or higher. I updated to 2.9.5 (and opened https://github.com/acquia/blt-vm/pull/9 to change the default value to 2.9.x). NOTE: without addressing this, your VM will not provision.
I defined my first several multisites. You may not “always” know what your multisites are out of the gate, but for this example I kew what I was doing. So I ran blt recipes:multisite:init to define the sencond and third site that I knew I wanted. BLT automatically added the database config into my box/config.yml file which you can see here https://github.com/mikemadison13/multisite/blob/main/box/config.yml#L65. BLT has some extensive documentation on this command here.
I manually modified box/config.yml per Beverly’s recommendation to ensure that the drupal database user has access to all drupal databases. See https://github.com/mikemadison13/multisite/blob/main/box/config.yml#L82
Next, I reviewed my sites directory to make sure that all of my database settings were setup properly. This did require a bit of manual intervention. See https://github.com/mikemadison13/multisite/blob/main/docroot/sites/second/blt.yml. Note that BLT uses the BLT.yml file to generate the local settings files. Each of your multisites will get its own BLT.yml which will be used for managing database credentials, drush aliases, etc.
Finally, I defined my multisites in an array in my PROJECT level BLT.yml. See https://github.com/mikemadison13/multisite/blob/main/blt/blt.yml#L6
There are many other tweaks to be made, but those are really only useful once we have a server. So now finally it’s time to provision the VM. Run vagrant up and let it run for the next 15-20 minutes. Warning: you do need sudo for this stage!
Drupal Setup
Once your VM is provisioned the next step is to install Drupal (single site) the first time. I would suggest doing something like this. Note: since we are running Drupal VM you should vagrant ssh so you’re inside the container.
blt setup
This should run very quickly given that acquia/drupal-recommended-project and BLT 12 default to minimal.
The next thing is to export your default configuration snapshot.
drush cex -y
I would also advise setting up a few additional things at this stage:
Install the default BLT config splits using blt recipes:config:init:splits
Setup your local drush aliases. See https://github.com/mikemadison13/multisite/blob/main/drush/sites/second.site.yml#L1 as an example of the alias and https://github.com/mikemadison13/multisite/blob/main/docroot/sites/second/blt.yml#L7 for the BLT.yml file for a given site.
From here, I usually re-install the default site with my config dump just to make sure everything is working properly, and to do any additional baseline config (like enabling additional modules that minimal doesn’t ship with by default). You can facilitate this by running
blt setup
<making changes>
drush cex -y
This will get you the baseline config from the profile and any modules you’ve enabled.
Next, I take advantage of the blt recipe to install default config splits.
blt recipes:config:init:splits
The next step is to actually start installing your multisites to test them out. You can do this easily with blt.
blt setup --site=<whatever site>
This will re-execute the setup, but on your first multisite. Any troubleshooting you need to do should be done here. You may need to fix db credentials in your multisite’s blt.yml or settings file.
Continue this process for each site.
Drupal Architecture
The last thing I would recommend while we’re working out details locally is to start implementing your architecture for things like configuration management. The splits we setup above are for environments. Are you doing some sort of site specific splits? Do you need profile splits? If you’re not sure what I’m talking about, check out my intro to Drupal multisite planning. But right now, you are in a super early state so it’s a great time to start setting up all the things you need to really build and manage these sites.
Warning: as a general rule, I strongly recommend minimizing the configuration diffs between your multisites. The more ubiquitous you can keep your configuration and features, the easier your platform will be to manage.
Continuous Integration and Hosting
Typically on the continuous integration front, you don’t want to do “multisite.” What I mean by this, is that many CI builds can start to inch up in time naturally over the course of a single site project. If you are trying to fully install 4 or 10 Drupal sites and do all the things in them during CI, that could be quite a long build.
Rather, my recommendation for CI is to build out a “representative” site that is a single site, but contains the features of all the multisites on the platform. We won’t dig into this now, beyond my recommendation to not attempt multisite in CI!
Finally, on your hosting provider you will need to setup your multisite. If you’re using something like Acquia Site Factory, this is a largely automated process. If you’re using Acquia Cloud for multisite, there are more manual steps involved.
Here’s some documentation for additional things you need to do to get up and running on Acquia Cloud.
The TLDR is that:
you need a database for each multisite (these have to be manually created in Acquia Cloud, they are automatically created in Site Factory)
you need a settings file in your multisite for each site (to know which database to talk to)
you need to either configure domains for each multisite AND/OR add symlinks to your file system
once you’ve deployed your codebase, you’ll also need to manually install each of your multisites
All of these things (and more) are covered in the cloud docs!
In Conclusion
Drupal Multisite represents one of the most complex and challenging implementation techniques for Drupal. It’s freaking hard, and it’s hard to maintain over time. The benefits of doing Drupal at scale are really significant (so the effort is well worth it if you have a lot of sites) but you should definitely give yourself plenty of time to familiarize yourself with the vast and significant differences between building and maintaining a multisite platform (as opposed the the relative easy of doing so with a single site).
Managing the domains of a multisite can be very complicated. Which strategy should you choose?