The advantages of Drupal 8 as a website platform are too many to list. Its power and flexibility are amazing. Its base of thousands of modules ready for installation means any reasonable problem is easy to solve. With its programmable interior any problem a website needs to solve can be.
Drupal is farily easy to keep up to date. However, when you updating software it depends on or works with, at the same time, the update process must be done carefully. Drupal provides a clear INSTALL file, but it does not go into the intricacies of updating when other systems are being updated too. Of course Drupal cannot predict what people need to do outside of Drupal "space".
Here we go through an update process that is safe and involves a lot of details. As you will see, the cornerstone of safety is that we DO NOT touch, in any way, the production system we are going to upgrade. Its running just fine, but without upgrades it will degrade, like any software will.
At the end of the update process, we end up with two web systems, the new updated version and the existing production system. When we convert the new system to "production", the predecessor web root and database are untouched. We can easily rolllback to the predecesor with just a few seconds of work and a restart of the webserver. As always, we start by doing full backups of the production Drupal site and its database ...
The First Step
Backing up a production site takes a few easy steps:
- Clear all cache files
- Set the site into maintenance mode
- Backup the web document root using tar
- Backup the web database using mysqldump
People use a wide variety of backup tools. We use the above because they are very reliable at doing their job and they are free. The actual commands in the shell are fairly simple so we'll ignore those details till later.
After the backups are complete (~10 minutes) we can safely put the website back online by unchecking the "site maintenance" mode checkbox and saving the result. Then we check the production website to make sure its operating normally.
Updating the Development Site
We use a command called "rsync". its widely known and reliable. We sync the production website source files ("PROD") to the destination site development machine ("DEV"). Rsync will synchronize ownership, permissions and files by adding new files, applying changes to existing files and deleting files on DEV that no longer exist on the source machine (PROD).
We run rsync is using a script that runs in a shell. When its done copying the document root and database backup to the DEV, then it hands control to an Expect script that runs on PROD and delivers shell commands to DEV to drop the old database and create a new updated database.
Rsync does a few other synchonizations too (web certificate files, web config files etc). After this synchonization process is done (about 5 minutes) DEV is running an exact copy of the PROD machine.
Another nice thing about rsync is that its simple replicate the above so DEV is also synchronized to an AWS machine instance somewhere on the planet. Now we are ready to begin updating Drupal 8 on DEV.
Downloading Drupal 8
Its easy to find the latest stable tar.gz file. The steps on DEV are:
- copy the latest Drupal tar file to the webroot directory
- use tar to extract the files
- change the name of new Drupal directory to something like "Site2" or leave it as is if you like. We prefer the simpler name.
Remember, we do not touch files or database of the original PROD site. This step takes about 5 minutes.
Gather differences between DEV and PROD
Our DEV runs a more up to date operating system, webserver and PHP version than the PROD machine does. We do this because problems with the existing PROD setup will show up sooner on DEV and we can plan better for the day when PROD starts to use these more up to date systems.
Its our experience that plenty of things go wrong on DEV when you upgrade Drupal on a newer OS, webserver and PHP binary. Thats ok because there is no effect on PROD and we learn what the fixes are (if any).
Updating to the new Drupal
Once we've unwrapped the new Drupal file on DEV you can read the UPDATE.txt file in core directory. That assumes your updating, not installing fresh. Update.txt describes accurately how to update. BE SURE to read the release notes because that will save a lot headaches and problems as you do the upgrade. Then,
- log in and put the DEV site in maintenance mode.
- if your site is managed by composer, run "composer update". Don't do this as root.
- Check the release notes and see if the settings.php file has been changed
- Make a backup of your settngs file. Apply differences to the new settings file if necessary
- Make other changes recommended if you need to.
At this point then, change ownership of all files in the DEV webroot to match your copy of PROD if you need to. Now, in your DEV copy of the PROD site:
- remove the "core" and "vendor" directories
- copy your composer.json file to composer.json.bak
- copy your ".htaccess" file and "robots.txt" files to backup copies too
Your DEV copy should have the following directories present
- libraries (sometimes not...)
Now CD into your new drupal update directory and copy all these files into your DEV copy of the PROD site:
cp -R * /path/to/your/installation
cp -R .[a-z]* /path/to/your/installation
You may run into permission issues, Fix them and re-run the above. You cannot ignore any error reported, no matter how small it seems. In the second command above, be sure to use the regex [a-z] or you will get an error about copying the dot files
Now you will need to update the new "composer.json" file. A quick way to do this is to run the program diff:
- diff composer.json composer.json.bak
- diff will report differences in composer.json with a left bracket "<" and
- differences in the backup file composer.json.bak with a right bracket ">"
- ignore the "<" differences (in the new composer.json file)
- you can copy and paste the differences from the old composer.json.bak file into your new composer.json file and run composer update or
- use composer require <module/module> to load in your modules based on the list provided by dfff (the ">" differences)
You may run into package problems with Composer. The last resort is to download the tar.gz file for what is causing the problem and install it into the updated Drupal, but first, run
- update.php so that the database is synchronized with the new version of Drupal
- then install the package in the usual way and run update.php again.
After this restart the webserver, database server and any others that the site uses. If there are error messages, fix them and make note of the fixes. Three things can happen
- the webserver wont start or
- the website will not run properly or
- everything is fine.
Assuming things are fine, browse the website and check different things and especially check the Reports (available updates, logs, and status. They should all be clear of unusual items (e.g. Complaints) :-)
When things go wrong
Most of the time, everything is not fine, so we have to examine log files to get at the root of the problems and find fixes for them. Key log files are:
- webserver access and error logs
- database access and error logs
- mail server access and error logs
- system log files
- Drupal log files
We always use Google too and often Stackoverflow.com to help find solutions.
The key method here is that we are dealing with a DEV installation completely separate from our PROD database or files added or deleted or changed in the webroot of PROD. Depending on the problems, getting the updates applied can take about one to three hours. If it all seems to go to hell you can delete the DEV files and directories and start over. Sometimes that is necessary.
Bringing the Updated Drupal Site Online
There are two status (states) to consider
- The database with the update requires no updates
- The database with the update does require updating.
We solve both by running Drupal's update.php script as mentioned below. Its pretty easy.
On the DEV machine with the now updated site:
- You're going to make a copy of the now updated DEV website directory,
- double check that the document root of the updated DEV site matches the directory you are going to copy by checking the httpd conf file on DEV
- copy this DocumentRoot directory to "site2" or "drupal-8.x.x" so that its a different directory name than the original site has on the PROD machine
- tar the new directory ("Site2") into a "file.tar" and gzip it.
- on the DEV machine, change the httpd config files to the new directory ("SITE2")
- restart the web server. make sure there are no errors
- browse the updated site to make sure it looks and acts fine
- run cron again from inside the updated website on DEV
- check the Reports -> Status page on the upgraded DEV website.
- There should be zero warnings or problems
- use "scp" to copy the tar file to the PROD machine if there are no problems
- there are other ways, but you need to get the tar file to the PROD machine
There should be zero warnings or problems. if you run into a problem...fix it. This time, we had to fix file permissions on the copy because the copy command did not copy a directory set to 777 permissions correctly. You will probably see the same error sometimes.
You may also have to change permissions on the new directory but if you copy using this command
- cp -dRpv site/ site2/
You probably wont have new permission problems. The key here is to stay within this bullet list of procedures until there are zero warnings.
You've been warned :-)
Bringing the New Site Online
This is the fun part. Its fun because there is absolutely ZERO possibility that you can harm the existing PROD site because you dont touch its database or its file structure.
Still, to be sure, follow these steps
- untar the file created on DEV into the same level directory as you have the PROD site. For example
- Site1 (original) (SITE-1) is in /var/www/html in a folder called /var/www/html/site1
- the new site should be in the folder /var/www/html/site2 (SITE-2)
- then you have site1 and site 2 folders
- in the new site (SITE-2)
- check the permissions, make sure they look fine. Especially the public directory sites/default/files
- if all looks good then fine, otherwise fix things
- Now, make a new database
- set the original PROD site into maintenance mode
- clear the cache
- dump the original PROD database using mysqldump
- create a new PROD database using this dump file with mysql
- mysql -e 'create database <new database name>'
- mysql -e '<new database name> < mysqldumpfileSite-1.sql'
- change the database name in the settings file in sites/default/settings in the SITE-2 directory to the new name
- grant privileges to the same user in the settings file to the new database
- mysqladmin -uroot -e 'grant all on <newdatabase.*> to 'user'@'127.0.0.1' identified by '<password>;'
- At this point you have a completely new updated website in your new SITE-2 directory and a new database
- bring the original PROD site out of maintenance mode.
- everything should be running fine.
- This is the good part.
- change the httpd config files to point to the new SITE-2 folder
- restart the web server and check its status. There should be zero errors
- Be careful at this point!!
- browse the newsite by running the URL/update.php script or the site will automatically go into a NEW install mode
- if the install.php file runs it overwrites the new database. this is NOT good. wipes out everything.
- after update.php runs then browse to the new site home page. If the site says its under maintenance then
- then go to /user/login and login as admin
- go back and adjust your settings file. comment out the ’site_offline’ line if you have one and
- set access to FALSE in the ‘free_access” entry line
- now browse the site and check the Reports. It should look exactly the same as what was running on DEV
- check the log files, status and updates reports. All should look the same as when the site was on DEV
- check content items, do some simple things, look around.
- clear the cache and run cron.php from the Reports area. All should work fine
- restart the database server and check for errors using systemctl status <your db>
- browse some pages you may have had trouble with in the past
- Run Composer Update. Do some more checking after you do that.
- Take the site out of maintenance mode once you feel everything is ok.
At this point something may still happen. Watching the error log for apache and the access log (using tail) and filtering with “Cut” can be a good idea too. You can revert to the old PROD site by changing the lines in the httpd config files to point back at the original PROD site and then restarting the webserver. This takes about a minute.
Thats why you do all this work above.
So in less than a minute you can rollback everything to the original PROD site if needed.
Even if you do have to Rollback, remember
- you have the full NEW PROD site running on your DEV machine.
- You can go back to DEV and fix problems that were missed, then
- follow procedures here to get the update working as the new PROD web system.
Be sure to check permissions in the file system again and be sure to set settings.php to 644 with the chmod program
- or if you like, Starlight can do all of this for you. The entire process above is LOCATION INDEPENDENT. We can login and do the work for you.
Just as a side note, I used to wonder why updating the Drupal site was often so painful. Now I realize its a lot of fairly simple steps, but if you miss 1 or 2 or do them out of order, all hell can break lose....!!
Quick Test Questions
Using Tar, as Root:
- tar -cvf backup.tar site/
- gzip backup.tar
Using mysql dump, as root:
- mysqldump <mydatabaseName> > mydatabase.sql
Copy the backup files to a reliable RAID array not physically part of the production machine so we know we will not lose those backup files. Of course, both the RAID array and production machine are protected by UPS machines.