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
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.phpfile off which the current
settings.phpfile is based
- Allows a (semi-)automated way to update
settings.phpfiles to incorporate changes
- Alerts the site maintainer when the
settings.phpfile 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
Put it in
web/sites/default, the same place as
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
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
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
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
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"
(Make sure you set the file to be executable,
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:
"post-update-cmd" : [
"post-install-cmd" : [
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.