Before starting our first Drupal 8 project several months ago we researched a number of topics, one of which was to define the optimal workflow of deploying changes to staging and production servers.
In Drupal 7 everyone was using the “Features” approach, which exported site configuration settings out of a database into code, by storing the configuration as files.
Originally the “Features” module in Drupal 7 was designed for a bit different purpose: to extract a feature from a site and have it independently ready in a library of features to be able to quickly apply to the new website.
Unfortunately, using “Features” for the purpose of configuration management had a number of disadvantages. You had to keep in mind lots of different issues that would come with it. One of them, for example, is that the “Features” module was good only for creating and changing but not deleting existing settings. Thus, if you wanted to delete an unnecessary field or bundle, you had to do workarounds. For example, we had to write “hook_update_NNNN()” that did just that.
Drupal 8 still has the “Features” module, but now it is finally doing what it is supposed to do - it allows you to select parts of the site configuration, extract this collection of configuration settings as a feature, and then save it to your features library. This serves the purpose of features collection that should help you in creating typical websites quickly.
Drupal 8 “Features” module is now based on the configuration management that is built into the Drupal core.
We have been successfully using Drupal’s Core configuration management functionality without even installing the “Features” module.
Drupal 8’s CM is a solid and complete configuration exchange tool without any of the disadvantages of “Features”. You can freely create, update, and delete configuration without the fear that you need to take care of anything else - even the fields deleted on development will get deleted when this kind of change is deployed to other environments.
One thing you should keep in mind though is if you are deleting a configuration (definition of a field or an entity) you need to be sure there is no data using that configuration (no nodes). Otherwise, the delete operation might fail.
The CM export results in a number of files, in our case, that number was over 800. These files are pretty well and logically organized. The config files are in json format and are quite human-readable. If approached very carefully, it can even be used to edit Drupal site configuration without clicking the website, which can boost your productivity tremendously. I have done search-replace in those config files and reimported them, which only took me 10 minutes instead of doing it all manually and slowly with a mouse, which would have taken several hours.
To set it all up, you need to uncomment and configure a couple of things in your settings.php file:
$config_directories = array(); $config_directories['sync'] = '../config/sync'; $config_directories['staging'] = '../config/staging'; $config_directories['live'] = '../config/live';
Please note the directory here is out of webserver’s reach. If you had them in your webdir, directly accessible by the webserver, then you would need to create some non-obvious directory names like in the following example:
$config_directories['sync'] = 'sites/default/files/config_PZQwz-SxqeASFq3ra_-OyfPZ3EOwOJqiK8uFferfSERFvasrFwar8reFser_4344aqJHEhga6Blcw/sync';
With this you can avoid security issues of anyone trying to guess your site configuration pathnames.
I think it is better placed outside of the webdir and to have names that are still comfortable to read.
With that configured you can launch the configuration import and export with drush cim and cex commands:
drush cex sync -y drush cim sync -y
Are you using a different approach that has any advantages over this one? If so, please comment and give everyone a hint.