Optimizing costs with Multisite Drupal applications
Introduction :-
I have written this article to share my experience and learnings acquired while setting up Drupal application in a multisite mode. When you talk about Drupal multisite setup, one has to opt for a subdomain or subdirectory approach.
Both the approaches work fine but have their own pros and cons which are discussed down the line. A subdomain approach requires purchasing domains which translates into cost whereas subdir saves you from that. Apart from that are other advantages of a subdirectory approach such as reducing management overhead, fewer code to maintain etc. I have discussed these things in detail below in the respective section.
The most common use case is subsite multi-site: One site for each domain site1.example.com, site2.example.com and so on. However, sometimes you want a subdirectory multi-site: One site for each directory example.com/site1, example.com/site2 and so on. Neither you can create a subsite/subdomain (because you don’t have access to DNS) nor you want to do it for SEO (Search Engine Optimization) considerations. Most interesting thing in multi-site Drupal Based hosting is each website will have its own database, content, themes but all sites will have the same codebase.
Below points are covered in this article:-
1. Background
2. Why Subdir ?
3. Prerequisites
4. Steps to follow
5. Pros
6. Cons
7. Recommendation
8. Conclusion
9. References
1.Background :-
Today, a lot of companies are going with multi-site setup as they can control their same codebase for all sites. Below are some of the use-cases that can be solved by using multi-site subdir Drupal
- If you have several sites that are all similar in functionality. In this situation, multi-site is a great solution for easier management of all the websites.
- If you need multiple sites with the same core, modules, themes or distribution.
- If you have limited resources and/or limited workforce and a lot of sites to manage.
2.Why Subdir ?
A sub-directory as the name suggests helps you setup sub-directories in your multi site drupal application as opposed to using subdomains for each site. It helps you address the problems such as -
- Overhead of managing multiple domains — When you have multiple sites hosted through a subdomain approach, you need to manage the registration and renewal process of such domains. Not to mention maintenance and testing of each subdomain every time you upgrade your site or release some new feature.
- Cost overhead — You have to pay for each subdomain you purchase and use in your multisite application.
Sub-directory approach helps you address above stated problems. In addition to that such setup is also beneficial in case you language translation requirement for multiple sites, for .e.g
- es.example.com/site1
- es.example.com/site2
3.Prerequisites :-
Below are the Prerequisites for this article
i.) Basic understanding of Drupal Structure
ii.) Understanding about Drupal application’s compile, build and deploy process using drush (Drupal shell) commands.
Here is the reference for Drush Commands :- https://drushcommands.com/
iii.) Already set up a Single Drupal site(for us our previous site was example.com and then we enhanced it to another 3 sites using a single domain) and then this article will guide you to set up a multisite subdirectory Drupal. You should have already installed php, mysql, drush, composer, nginx to achieve the basic setup.
iv.) The Drupal application discussed during the article have 4 sites example as below: example.com can be used your website landing page
A. example.com
B. example.com/site1
C. example.com/site2
D. example.com/site3
v.) Basic understanding of Linux Directory Structure
vi.) Basic understanding of Nginx Web Server
4. Steps to follow :-
Installing and setting up multi-site isn’t as simple as other Drupal features, however, the following instructions will help you enable multisite feature up and running perfectly. Let’s dive into setting up a new site with a single code base.
A.) Putting Entry inside sites.php :-
Navigate to website root/sites/ and locate sites.php file. Before making any changes to sites.php, take a backup of this file and edit sites.php by using choice of your editor (i.e. nano, vi )
In this article we have four sites on a single domain i.e. example.com, example.com/site1, example.com/site2, example.com/site3 and entry in sites.php should be as shown below.
$sites[‘example.com’] = ‘example’;
$sites[‘example.com.site1’] = ‘site1’;
$sites[‘example.com.site2’] = ‘site2’;
$sites[‘example.com.site3’] = ‘site3’;
B.) Creating Directory structure for Multi-Site
As we already have example.com setup, in that case we already have one directory called “abc” inside the webroot/sites directory. Hence we need to create another 3 directory for other 3 sites. Jump into webroot/sites and run below commands -
mkdir site1mkdir site2mkdir site3
Make sure all of the above directories should have atleast 775 permissions.
C.) Creating settings.php for all sites :-
Now we need a settings.php file for all three newly created sites. Lets create a copy of default.settings.php from default directory( which is inside your webroot/sites directory) to newly created site1, site2, site3 directory and name should be settings.php
cp <webroot>/sites/default/default.settings.php <webroot>/sites/site1/settings.phpcp <webroot>/sites/default/default.settings.php <webroot>/sites/site2/settings.phpcp <webroot>/sites/default/default.settings.php <webroot>/sites/site3/settings.php
D.) Creating Symlink :-
Now we need to create symlink for all of our 3 sites because if we don’t create symlink nginx will not get index.php file for respective sites.
Please note that you need to create a symlink with the same name that you have put in sites.php and the same name that you have created directory
Go to your webroot folder and run below command to create symlink
cd <webroot>ln -s . site1ln -s . site2ln -s . site3
Creation symlink at correct location is an essential step because mistake in doing so won’t allow nginx to find out “index.php” and will through error “Request URL not found”
E.) Database Modification or Creation:-
Now we need to proceed with the Database Part. Depending on our requirement we can use our existing Database that’s already being used by the main site i.e. example.com or we can create a new database
i.) If you want to use an existing database already used by another site(here that Database is being used by the main site example.com) then you need to modify settings.php file for every site. Let’s take site1 as an example.
Open <webroot>/sites/site1/settings.php and paste the data from existing site’s settings.php to the end of this site.
Remember to change the value of “$settings[‘config_sync_directory’]” from previous directory to current directory name i.e.
from “../config/abc/sync” . to “../config/site1/sync”
You will find the config directory inside one path back to the webroot .
ii.) If you want to use a new database then you need to create one database going inside the database prompt and running command “create database site1;” which will create one blank database for “site1” , you need to do the same for the other two sites as well.
After creating new database if you want to use data/contents/themes of old database then you need to create a backup of that existing databases and you need to restore to the newly created Database as shown below
a.) Go inside <webroot>/sites directory :-
cd <webroot>/sites
b.) Creating Backup for Database “abc”
mysqldump -u <database username that you will get from settings.php for abc site > -p<Password for the database which also you will get from settings.php> abc > /tmp/abcdatabasebackup.sql
For e.g. — If username for “abc” database is “drupal” and password for “abc” database is “1234$” then command will looks like below
mysqldump -u drupal -p1234$ abc > /tmp/abcdatabasebackup.sql
Please note that there is no space between “-p” and password for that database
c.) Restoring Database Backup to site1
drush -l site1 sql-cli < /tmp/abcdatabasebackup.sql
After Database Restoration done, ensure to check settings.php and make relevant changes in line starting with “”$settings[‘config_sync_directory’]” as described in Point 5a)
F.) Creating “files” directory :-
Go inside <webroot>/sites/site1 and check there should be a “files” directory if you are restoring any old Database. If you created a new database and left it blank without restoring anything then you need to create a “files” directory inside your each subdirectory for all of the sites.
This files directory will contain all images, media files and make sure this “files” directory should have at least “775” permission and should be owned by “nginx:nginx”
G.) Nginx Configuration
Now, we need to do some modification in nginx so that nginx can understand newly created sites.
If you are using centos then go inside the “/etc/nginx/conf.d” directory, you will get a nginx configuration file. However, it can vary depending on your web server configuration and sometimes you can also have a nginx configuration file inside “/etc/nginx/sites-available/” directory as well.
If you are using “Ubuntu” you will have the nginx configuration file inside “/etc/nginx/sites-available/” most of the time.
We need to mention specific location directive inside nginx as shown below for 3 sites.
location /site1 {try_files $uri /site1/index.php?$args;}location /site2 {try_files $uri /site2/index.php?$args;}location /site3 {try_files $uri /site3/index.php?$args;}
Please note that if you do not set “location” in nginx then it will give you “Page Not Found” error as Nginx can’t locate “index.php”..
H.) Configuring Drupal for this subsites:-
Now you need to go to the browser and hit “https:/example.com/site1” for site 1 ( replace site1 with site2,site3 while testing other sites) , login with your user id and password which will take you through new drupal configuration for this site.
If you get error that states — “files” directory don’t have write permission then run below command
chcon -R -t httpd_sys_rw_content_t <websiteroot>/sites/site1/files
If you get the same error for “settings.php” you need to run the same command for settings.php as well. Also make sure that “settings.php” should have 444 permissions.
chcon -R -t httpd_sys_rw_content_t <websiteroot>/sites/site1/settings.php
I.) Changing UUID :-
After Drupal is configured then you need to change uuid for that particular database.
Enter into “<website root>/../config/sync” and open “system.site.yml”
locate the “uuid” parameter for this particular site that is “site1” , copy that UUID and paste it after “uuid” in the below command. Once uuid is set check the same with “config-get” command.
drush -l site1 config-set “system.site” uuid 16799278-c199–46cf-961b-58f3a0fbc980drush -l site1 config-get “system.site” uuid
Once the above mentioned changes are done, run all the below commands in sequence -
drush -l site1 cr → For Cache Rebuilddrush -l site1 cim -y → For Import Configurationdrush -l site1 cr →Again For Cache Rebuild
After all of this is done you can access your site — https://example.com/site1
Repeat all the above mentioned steps for setting up site2 and site3.
5.PROS:-
i.) First advantage of Drupal multi-site is that we are using the single codebase of all of our sites , in that case developers and administrative tasks are easier with a single codebase.
ii.) Code and library updates only need to be done once.
iii.) Though all sites contain the same codebase but you can customize all the sites with selected themes/modules.
iv.) This also gives us an advantage on costing. A single hosting plan that supports all of the traffic from all the sites might be cheaper than hosting individual sites.
6.CONS:-
i.) If a site decides to customize functionality provided by a Features module, then it would lose any further updates to the module, as they have deviated from it.
ii.) You might want to reconsider using Drupal’s multisite configuration, in situations where the administrators for all of the sites being run from the same code base or the same person or a small group with a high level of mutual trust.
iii.) Since we are hosting all our 4 sites on a single server hence this can be considered as a single point of failure, but we can use Load Balancer/Auto Scaling to get rid of this.
iv.) Please note that this point is applicable to Public Cloud but may not be held true for Private Cloud.
v.) If any problem with the code happens then it will affect all of the sites
vi.) Drupal is subject to security vulnerabilities in some cases, if not handled properly; bugs which allow an unauthorized user access to Drupal core code. Once a hacker has access to your core code, they have access to all your sites through a single hacking attempt. Non multi-sites setup may require separate attacks, which may offer sufficient time for the vulnerability to be remediated.
vii.) Also we need to do a proper maintenance of this multi-site from Infrastructure as well as developer end.
7.Recommendation while using Multi-site :-
i.) While you have built your Drupal multi-site Setup always use drush for new deployment or site upgrade. Using drush is much easier when you have a multi-site setup, as drush allows you to specify different site’s name while building the code or upgrading it.
ii.) Always use sites.php to manage sites, you will get reference of sites.php from <webroot>/sites/sites,php(Drupal 7) and example.sites.php (Drupal 8)
8. Conclusion:-
This article explains how to create subdir multi-site drupal. Managing a multi-site drupal application using one domain, one codebase is much easier with multisite subdir setup. Appropriate measures and precautions can help us overcome the cons stated above and makes usage of Drupal multi-site Setup hassle free. Even large organizations also nowadays are going with this technique and we can say it’s a good future with Drupal multi-site.People who are migrating from single site to multi-site, can use this article reference.
9. Reference:-
i.) Drupal — Open Source CMS | Drupal.org
ii.) Multisite Drupal | Drupal | Drupal Wiki guide on Drupal.org