Configuration Files Specification #
Various specifications attempt to define configuration files and file formats. This specification establishes where these files should be looked for, in which order, and how precedence, masking, extensions and overrides work.
The purpose of the rules defined here is to allow OS vendors to implement the
hermetic-usr pattern, where all vendor files are shipped in the vendor tree itself
/usr/), including configuration files with system defaults, while allowing local
or vendor overrides without modifying the original files, for easier management. This is
especially beneficial for image-based deployments, where the vendor tree is read-only.
These rules are derived from existing real-world usage from the systemd project and the libeconf project. It is highly recommended to use libeconf, which is readily available and maintained in all major distributions, rather than reimplementing this specification locally.
This specification is agnostic toward the actual format and content of the configuration
files, the precise path used under each top-level hierarchy, and also toward the
filenames and extensions, with the exception of the
.d/ notation for drop-ins
directories. It is strongly encouraged to enforce a specific suffix for the configuration
files, in order to disambiguate (e.g.: with backup files), but the choice of which suffix
to use is left to each implementation.
Storage Directories and Overrides #
In order to allow shipping system defaults owned by the OS vendor, while at the same
time letting local users or admins override those defaults,
/etc/ are both
supported for storage of configuration files, with the latter having higher priority.
The precise location under
/usr/ is left open for the implementation to decide - it
could be hard-coded to
/usr/lib/ or it could be left to each application to pick from
various options, such as
Programs must work correctly if no configuration files are found in
/run/ is also supported for ephemeral overrides.
/usr/lib/foo/bar.conf provides the default configuration file.
/run/foo/bar.conf is present and supported, it would take precedence over
Finally, a user can create
/etc/foo/bar.conf which would take precedence and
completely override both.
As a special override case, it must be possible to mask files across different
locations by creating a symlink to
/dev/null or an empty file.
For example, an empty
/etc/foo/bar.conf means that
masked and thus not parsed.
All configuration paths must support drop-ins. Supporting drop-ins means that in addition to parsing a full configuration file, an implementation also must parse all files in the drop-in directory associated with it, and merge the result in lexicographic order. Drop-ins are not full replacements, but must allow specifying a subset of settings present in the main configuration files.
For example, in addition to parsing
/etc/foo/bar.conf.d/b.conf must also be parsed, in this order.
Drop-ins always have higher precedence than the configuration file they refer to, regardless of under which hierarchy they are stored.
For example, settings in
/usr/lib/foo/bar.conf.d/a.conf must override settings in
If a config file is masked, drop-ins must still be parsed, unless they are masked themselves.
For example, even if
/usr/lib/foo/bar.conf is masked by an empty
/usr/lib/foo/bar.conf.d/a.conf must still be parsed and applied, unless there is also
/etc/foo/bar.conf.d/a.conf, in which case the drop-in is masked too.
Drop-ins are not recursive, so a drop-in cannot have a directory of drop-ins.
/etc/foo/bar.conf.d/a.conf cannot be overridden by
/etc/foo/bar.conf.d/a.conf.d/b.conf, and the latter must be ignored if it exists.
Drop-ins without Main Configuration File #
Optionally, schemes with only drop-ins, without a ‘main’ configuration file, should also be supported by implementations. In such schemes many drop-ins are loaded from a common directory in each hierarchy.
are all loaded and parsed in this scheme.