Every content type, view, field, and permission on your Drupal site lives in the database — which means it lives in exactly one place, and “deploying a change” means clicking the same buttons twice and hoping you clicked them the same. Configuration management fixes that: settings become YAML files, files go in Git, and Git goes wherever your code goes. You’ll need drush and a site already under version control.
Set the config sync directory
Drupal needs to know where exported config should land. Put it one level
above the web root so the files are in your repo but never web-accessible.
In settings.php:
$settings['config_sync_directory'] = '../config/sync';
Then create the directory and make sure Git will see it:
mkdir -p config/sync
Export and read what came out
One command turns the database’s settings into files:
drush config:export
(drush cex for short — you’ll be typing it a lot.) Open the directory and
poke around. Every file is one piece of configuration: system.site.yml is
your site name, views.view.frontpage.yml is the front-page view, and so on.
Nothing magical — just your site, written down.
Commit the baseline
This first commit is the “known good” snapshot every future diff compares against:
git add config/sync
git commit -m "Config baseline: initial export"
One thing that does not belong in these files: secrets. API keys and
passwords should live in settings.php overrides or environment variables,
not in a repo. If you spot one in the export, move it before you push.
Make a change and diff it
Here’s the payoff. Change something small in the admin UI — the site slogan, say — then:
drush config:export
git diff config/sync
The diff shows exactly what your click did: one line, in one file. That’s the whole trick. Every settings change your site will ever have can now be reviewed like code, blamed like code, and reverted like code.
Commit it:
git add config/sync
git commit -m "Update site slogan"
Import on the other environment
Push, then on staging (or live), pull the code and load the files back into that environment’s database:
git pull
drush config:import
drush cache:rebuild
Drush lists everything it’s about to change and asks first — read that list. If it wants to delete a view someone built directly on live, that’s not a bug in the tool; that’s the tool telling you someone’s been editing production by hand. Export their work into the repo before it gets paved over. Like a portage, the first trip carrying everything is the heavy one — after this, changes travel one small diff at a time.
Verify config status comes back clean
The check that says you’re done:
drush config:status
You want: No differences between DB and sync directory. That one line
means the database and the files agree — what’s deployed is what’s in Git,
on every environment. From here on, the habit is simple: change, cex,
commit on the way out; pull, cim, cr on the way in. If config:status
ever shows drift you didn’t make, that’s your early warning that someone’s
editing an environment directly — and now you have the receipts to prove it.