Usually I just let the UI do the initial setup and I tinker with it until I have something basic working. It’s just convenient that way. One could of course use APIs or fiddle directly with config.xml, but for all the boiler plate stuff, I personally find it more efficient to just let GOCD do its thing through the UI.
If it’s in version control, it’s still up to you to place the file in the config dir before starting the server. We aren’t doing that for our use case. While we keep backups on S3 in case we need to restore an old snapshot, for normal day to day, we just keep our configs on a persistent disk and that gets bindmounted to the config directories when the docker containers start/restart. So the config files and DB are persisted between deploys. We’re not using puppet or anything like that. Just docker and some simple bash scripts to control start/stop, and fetching of new app/plugin versions. Configuration happens by way of the bindmounts ensuring that the configs exist in the expected locations.
Most of the incremental changes are done through the UI (whether that’s using the “actual” UI, or the copy-edit-paste method I described earlier. It’s not “sexy” like using the API or some other config tool, but it feels natural and works for us. Most of the time we’re just adding/updating a new elastic profile or a config repository (for pipelines as code), and it’s pretty straightforward to do in the UI. For pipeline configs, we usually use the pipelines as code feature and config that in source control. We mostly use the YAML and Groovy syntaxes for that.