When you install a Drupal site, a settings.php
file is created (either by you, or by the installer) to contain various settings specific to your site (such as database configuration, trusted hostnames, etc.). This is done by taking a copy of a file provided by Drupal core, default.settings.php
, and adding or modifying the required lines.
As Drupal develops, additional features mean new things going into default.settings.php
.
For example, after a long discussion, a new entry was added to default.settings.php
with effect from Drupal 9.2
# $settings['update_fetch_with_http_fallback'] = TRUE;
This mitigates a potential man-in-the-middle attack with checking for updates to core and contributed modules. The point here is not to discuss that issue. This merely serves to illustrate something: Any Drupal site created before 9.2 will have its settings.php
file based off the earlier default.settings.php
file, and so won't have this entry with associated documentation comments.
This is going to become increasingly important. Before Drupal 8, major new Drupal releases would often involve creating a new settings.php
file. Now, this file could persist as Drupal moves through 8.x, 9.x, 10.x, etc.
There needs to be some way to keep track of changes to default.settings.php
between releases of Drupal core, so that any individual site's settings.php
file can keep pace. Expecting site maintainers to comb the extensive release notes for every minor core release is not going to work; apart from the chance something might be missed, there is also the fact that sometimes smaller changes in a major release are documented in the release notes of a beta or release candidate.
To work, we need a solution that
- Keeps track of the
default.settings.php
file off which the currentsettings.php
file is based - Allows a (semi-)automated way to update
settings.php
files to incorporate changes - Alerts the site maintainer when the
settings.php
file has become stale.
This post will offer a solution, running through those 3 requirements
Keeping track of the defaults for the current settings.php
When you install your Drupal site, take a copy of default.settings.php
. I'll call it last.default.settings.php
.
Put it in web/sites/default
, the same place as default.settings.php
.
If your site is tracked with some kind of version control, make sure that file is included.
You now have a file that matches exactly the default.settings.php
file used to create your site's settings.php
file for the first time.
Checking when something has changed
We'll get to automating this in a bit.
But, for now, after any core update, you can run the following to check to see if default.settings.php
has changed since you created settings.php
.
diff -u web/sites/default/last.default.settings.php web/sites/default/default.settings.php
That command will return nothing if nothing has changed, or a diff of the changes if something has.
Incorporating changes (semi-)automatically
We can use that diff to change settings.php
to incorporate any changes
cd web/sites/default
diff -u web/sites/default/last.default.settings.php web/sites/default/default.settings.php > settings-merge.patch
patch --dry-run settings.php < settings-merge.patch
As long as you're happy with what the dry-run says will happen, follow this with:
patch settings.php < settings-merge.patch
rm settings-merge.patch
Lastly, we need to copy the (changed) default.settings.php
file. Your settings.php
file is now based off the updated version, so we need to update the copy we're keeping to track this
cp -a default.settings.php last.default.settings.php
Take care, if patch creates a file called settings.php.orig
containing the unaltered file, remove that before checking the changed version back into version control. If you're using version control, you don't need a separate copy of the old file anyway.
This is all only semi-automated, because it's possible that the patch won't apply cleanly (for example, if the changed portion of default.settings.php
is too close to site-specific modifications you had made), in which case you'd have to make the changes manually.
Alerting the site maintainer
You could run that diff command manually after each core update. But it would be nice to automate that.
Fortunately, this is easily done.
I have a directory inside my composer root folder named hook-scripts
. Your mileage may vary as to where you choose to put files like this, but working with my directory structure, create a file in hook-scripts
named check-default-settings
.
#!/bin/bash
DIFF=$(diff -q web/sites/default/last.default.settings.php web/sites/default/default.settings.php)
if [ ! -z "$DIFF" ]; then
echo -e "\e[31mdefault.settings.php file has changed\e[0m"
fi
(Make sure you set the file to be executable, chmod +x
)
If you execute that script, it will return nothing if default.settings.php
is unchanged. But if your last.default.settings.php
file no longer matches default.settings.php
, it will print a message to that effect in red letters.
Now all we need to do is tell composer to call this script after each installation or update. I'll assume here that you know how to put pre / post update / install scripts into composer.json
. But you want something like this:
"scripts": {
"post-update-cmd" : [
"~/composer/hook-scripts/check-default-settings"
],
"post-install-cmd" : [
"~/composer/hook-scripts/check-default-settings"
]
}
Now, every time Drupal core is updated (indeed, anything is updated) your script will run. If default.settings.php
has changed, you'll be prompted in red lettering. You can then go and run the diff / patch commands above to make sure those changes are included for your site.
Comments
Alternative Approach
My approach is to have a small custom settings.php, load the lastest defaults and tweak, eg:
include $app_root . '/' . $site_path . '/default.settings.php' ;
$databases['default']['default'] = array (
...
...
That works
Yes, that works. Simply include the
default.settings.php
file, and then add what you need to customise.I don't actually put my database credentials in
settings.php
. They go insettings.local.php
, so if that was all I usedsettings.php
for, the file would be very small - just the include statement.Thanks for this alternative. I'm sure it will help some, as it's certainly cleaner and simpler to set up. I think the reason I prefer the approach I use is that the comments documenting each entry in
settings.php
are very helpful, and there's something accessible about having all the configurable options and their docs in place. But advantages both ways, and I like yours too.Oh agreed. One still needs to
Oh agreed. One still needs to check for changes (and their impact) to the default settings. Just another thought to add into the mix :-)
Add new comment