Hi,
I’m asking for opinions and preferences.
There is no right or wrong.
Scenario:
I have a tool (server component, api only, no gui) that has a config file and no per-user adjustable things. The admin can change things, of course.
Now the tool gets plugins, where to configure them?
- All in one config file with plugins having a section for their things,
- plugins get their own config file.
- the main config points to a storage (database) with config options for everything, a kind of variant of 1.
- something else/better
Hoping for a civil discussion ;)
Cheers
Grumpy
Imo, plugins should have separate config files, with uniform, consistent formatting. Separating them ensures that plugins never modify primary configuration details, they can be updated independently, or deprecated without affecting future functionality. It also means you can take regular and reliable backups of each config.
I like how Symfony does it in PHP:
Config files have well known locations (e.g.,
<project root>/config
for main project, and<plugin root>/Resources/config
for plugins) for config files. The main config is loaded into memory, and then each plugin config is loaded and merged into the main config.This has several advantages:
- Each path allows for auto-discovery of new config files
- The config files can be in any file format that the app supports read (e.g.,
.ini
,.yaml
,. php
, etc) - The plugin config can overwrite anything in the main config
- Environment-specific configs can be loaded based on a
$ENV
variable (e.g.,dev
ortest
), or by ignoring files in your VCS
For Symfony, it is more complicated than that in that they also have mechanisms to define valid configuration values and their expected types, but that’s beyond the scope of your question.
Database configuration is an interesting choice. It certainly would help with scaling across multiple servers. Of course there is still a need for local configuration to access the database, but how often does that really change? But if you don’t need to scale more than two or three servers, it might be a bit of overkill IMO.
A complicated plugin ecosystem (e.g. Jenkins) makes for a terrible use experience. It’s annoying to configure a bunch of config files. Managing dependencies can be a complete nightmare. these problems also complicate your ci/cd.
So I’ll offer a slightly different answer. I prefer a single file instead of splitting up the config. And I’ll use OpenTelemetry as an excellent example of why. the plugins are compiled right into the app binary. This offers a ton of advantages, including a great reason to merge all of your app configs in a single file.
This really only works well if you have a good app though.
Depends on how “separate” the plugins are.
Single config file eases configuration of a service you consider one, and extend with plugins.
If the plugins reach a certain size, or are so distinct or separate, it may be preferable have separate configs.
ok, thank you all for your replies.
Both sides have good arguments, that’s why I was posting this, many of the argument came up as well when arguing with myself.
Counting the posts/upvotes, split config files seem to be the most popular choice or is it just because of they were the oldest and had time to collect more upvotes? Questions after questions :)
Thanks and cheers
Grumpy
Heh. Those of us with experience with these approaches know that there are plenty of wrong answers here, at least. The vote counts seem to be doing a pretty good job for anyone who wants a hint…
Annecdotaly, I just pushed a costly release to correct problems caused by my naive past use of approach 1.
Edit: a good rule of thumb for civil discussion is to use “I / me” statements, so:.
- I just had the all one file approach cause me a bunch of pain.
- I appreciate this approach where I find it. One config file per separately maintained code base is great.
- I actually do use a database to configure most of my network. I push my configuration decisions from my own database, into flat config files, with Ansible. Having the end product require another database complicates my efforts significantly. It’s not too bad if the product provides a command line option for each config change.
- I appreciate products that configure everything in one flat file per develeoper/maintainer, which is essentially option 2. This allows me to solve advanced use cases with my own configuration database, Ansible orchestration, and Jinja config file templates.
I’d try to share the config space as much as possible. Options 1 and 3 make sense then.
What feels “right” to me, when using NixOS and its module system, is that all config has the same shape, and is therefor easily moved to a different section, or to a section that is shared by a subset of plugins.
Con: It could lead to bad practices like strengthening dependencies between plugins (if they hard code to use a specific config option of another plugin).
Pro: But if you can discourage that, or use “deprecated pointers” to the new location of an option, the ease of moving shared config options to a more generic level can make it easier to maintain the total configuration. Developers of the separate plugins can build on what others have already done, and even synergize functionality (add a convenient integration if they see another option configured).
If some options are “secret”, though, and you don’t want those shared, they should either be in their own config (easier), or you’d need some access control on the configuration storage/file for each plugin (more work). Allowing a plugin to have a separate file for credentials, for instance, could be a good choice.
As Flatfire mentions, another issue can arise if plugins can modify the config. I assumed config to be read-only for the software, only editable by the admins, and never by the tools themselves.
As it is a more theoretical question or a question for the next time I need this, making config file(s) read-only and giving guidelines on how to structure the config values is possible. good points. Applies to all possible solutions 1-4 ;)