Configuration management in Drupal 8

To migrate settings from development to staging and production environments, we (mis)used the features module in Drupal 7. In Drupal 8 we have configuration management. With configuration management you can have a file-based workflow for moving settings around, meaning you can put your database settings in files. These files can be added to version control and imported on staging, production or your teammates development environment.

how does it work?

With features in Drupal 7 you there were lots of cases where settings could not be exported, or did not work as expected. In Drupal 8 the whole settings system is build differently. Modules have their default configuration supplied in Yaml files like this example of the site settings, system.site.yml:

uuid: 34475f01-4ada-4697-b031-498440539724
name: 'Drupal 8!'
mail: admin@example.com
slogan: ''
page:
  403: ''
  404: ''
  front: /node
admin_compact_mode: false
weight_select_max: 100
langcode: nl
default_langcode: nl
_core:
  default_config_hash: yXadRE77Va-G6dxhd2kPYapAvbnSvTF6hO4oXiOEynI
mail_notification: ''

This file is not the template form the core system module but a copy from my sandbox site's configuration. All settings are exportable to settings files now, which is great.

Settings can only be moved between sites which are clones of each other. In other words, you can not export settings from site a to site b. A clone must be created by exporting the database and use it for all the sites instances (development, staging & production).

setting it up

Drupal creates a configuration directory in /files if no custom directory is setup. The directory name contains a hash and a .htaccess file, still you do not want your settings in the public files directory.

Therefore setup a config directory, preferably outside of your Drupal docroot like ../config/sync You can setup the directory for configuration in your settings.php file, by adding the following line near the end of the file:

$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync';

Make sure the directory exists. Setup this directory on all your environments, so also staging and production.

Now you can make your first settings export. I use Drush for this stuff, you can also use the interface Administration > Configuration > Development, make sure you enable the 'Configuration Manager(config)' core module.

To export the settings using Drush issue the following command:

drush config-export

In this example we use only one config directory, which drush uses will by default, so we do not need to specify one. You can add the configuration to your version control system.

If all goes well your local setup is ready. Now you can export your database to the staging and other environments you want to be moving your settings to. You will only have to export your database only once, to setup syncing.

On your staging environment you can import settings from version control by importing the configuration from disk, by using the following command:

drush config-import

You now have successfully migrated configuration from one instance of your site to another. Effectively the above steps do not import anything since you already imported the database, so the settings are the same anyway. You can now follow the export, commit, checkout and import steps with new settings.

advanced stuff

It is really nice to have the same settings in all your environments. Still there are settings you want to be able to configure on a per instance base. For example Solr settings. You can overwrite configuration using settings.php, like you could in Drupal 7. See the following example to alter the site name:

// Overwrite single settings.
$config['system.site']['name'] = 'My first Drupal 8 site';
$config['system.site']['slogan'] = 'This slogan in set in settings.php';


// Overwrite multiple settings using one array.
$config['system.site'] = [
  'name' => 'My first Drupal 8 site',
  'slogan' => 'This slogan in set in settings.php',
  'page' => [
    403 => '/node/1',
    404 => '/node/2',
    'front' => '/node',
  ],
];

When overriding settings, you can use the longer array() syntax aswell as the short array syntax I used in the example.

It is important to note that the settings forms do not reflect the overrides. This can be confusing to both the administrators as developers. When you export your settings overrides are not exported, which is a good thing through. There is an issue on drupal.org about the settings forms not reflecting the actual possibly overridden configuration.

gothca's

To conclude this article I would like to share some best practices, for working with configuration management.

  • configuration files can contain secrets, like api key's passwords etc. Be mindful about this, when checking in these files in version control.
  • Be nice to your team mates and never break the configuration in your VCS, by checking if the settings import properly before committing and pushing. first pull, then export and review the changes. Reimport the settings to verify nothing breaks. Finally commit what you need.