How do I manage core and module updates along with config management between environments?
Yes, the referenced issue is related but I think this deserves a separate answer.

I agree this situation isn't fully satisfactory, but it's not too much of a problem.

In most environments, it won't be possibly to avoid manual configuration changes on production entirely. For example, contact forms are configuration (and not just a single file but 3 + 2 * number_of_fields) and users will likely create new ones without going through staging.

That basically means that you have to live with the situation that there can always be changes on production that are different from what happened on staging/dev. And that you have to treat the configuration on production as the master, unless you're deploying specific changes.

My process for deploying configuration changes usually looks like this:


Do the changes, commit them to a feature branch.
Export the configuration from production and commit it to whatever branch you use for that (for me, that's usually a branch called "production")
Merge your changes into that. Resolve conflicts if necessary.
Deploy the code to production.
Verify the configuration changes, make sure that ther are only known changes that know you prepared for deployment.
Import the configuration.


Module updates add the additional problem of update functions. If you have those, you need to run them between steps 4 and 5. Usually, those aren't a big problem unless they create new configuration with new UUID's. Then you have a problem if you want to import the same configuration entities from the staging config since those would have different UUID's and it would lead to deleting and re-creating them. You have to merge back the changed configuration from production before you can do that.

In general, I'd recommend to not mix module updates with feature/configuration deployments. Do module updates first, export the configuration again, then deploy again with new configuration.

Note that enabling new modules isn't affected by this, unless the module is installed by an update function. But if you deploy new modules through an updated core.extension module list, the config system supports that explicitly by taking the new configuration from your configuration export and not the module's clean default installation. So it's perfectly supported to enable a module on staging, customize its default config (not just simple configuration but also views and so on) and then deploy it to production.