10.7. Configuration files

10.7.1. Definitions

configuration file

A file that affects the operation of a program, or provides site- or host-specific information, or otherwise customizes the behavior of a program. Typically, configuration files are intended to be modified by the system administrator (if needed or desired) to conform to local policy or to provide more useful site-specific behavior.

conffile

A file listed in a package’s conffiles file, and is treated specially by dpkg (see Details of configuration).

The distinction between these two is important; they are not interchangeable concepts. Almost all conffiles are configuration files, but many configuration files are not conffiles.

As noted elsewhere, /etc/init.d scripts, /etc/default files, scripts installed in /etc/cron.{hourly,daily,weekly,monthly}, and cron configuration installed in /etc/cron.d must be treated as configuration files. In general, any script that embeds configuration information is de-facto a configuration file and should be treated as such.

10.7.2. Location

Any configuration files created or used by your package must reside in /etc. If there are several, consider creating a subdirectory of /etc named after your package.

If your package creates or uses configuration files outside of /etc, and it is not feasible to modify the package to use /etc directly, put the files in /etc and create symbolic links to those files from the location that the package requires.

10.7.3. Behavior

Configuration file handling must conform to the following behavior:

  • local changes must be preserved during a package upgrade, and

  • configuration files must be preserved when the package is removed, and only deleted when the package is purged.

Obsolete configuration files without local changes should be removed by the package during upgrade. 11

The easy way to achieve this behavior is to make the configuration file a conffile. This is appropriate only if it is possible to distribute a default version that will work for most installations, although some system administrators may choose to modify it. This implies that the default version will be part of the package distribution, and must not be modified by the maintainer scripts during installation (or at any other time).

In order to ensure that local changes are preserved correctly, no package may contain or make hard links to conffiles. 12

The other way to do it is via the maintainer scripts. In this case, the configuration file must not be listed as a conffile and must not be part of the package distribution. If the existence of a file is required for the package to be sensibly configured it is the responsibility of the package maintainer to provide maintainer scripts which correctly create, update and maintain the file and remove it on purge. (See Package maintainer scripts and installation procedure for more information.) These scripts must be idempotent (i.e., must work correctly if dpkg needs to re-run them due to errors during installation or removal), must cope with all the variety of ways dpkg can call maintainer scripts, must not overwrite or otherwise mangle the user’s configuration without asking, must not ask unnecessary questions (particularly during upgrades), and must otherwise be good citizens.

The scripts are not required to configure every possible option for the package, but only those necessary to get the package running on a given system. Ideally the sysadmin should not have to do any configuration other than that done (semi-)automatically by the postinst script.

A common practice is to create a script called package-configure and have the package’s postinst call it if and only if the configuration file does not already exist. In certain cases it is useful for there to be an example or template file which the maintainer scripts use. Such files should be in /usr/share/package or /usr/lib/package (depending on whether they are architecture-independent or not). There should be symbolic links to them from /usr/share/doc/package/examples if they are examples, and should be perfectly ordinary dpkg-handled files (not configuration files).

These two styles of configuration file handling must not be mixed, for that way lies madness: dpkg will ask about overwriting the file every time the package is upgraded.

10.7.4. Sharing configuration files

If two or more packages use the same configuration file and it is reasonable for both to be installed at the same time, one of these packages must be defined as owner of the configuration file, i.e., it will be the package which handles that file as a configuration file. Other packages that use the configuration file must depend on the owning package if they require the configuration file to operate. If the other package will use the configuration file if present, but is capable of operating without it, no dependency need be declared.

If it is desirable for two or more related packages to share a configuration file and for all of the related packages to be able to modify that configuration file, then the following should be done:

  1. One of the related packages (the “owning” package) will manage the configuration file with maintainer scripts as described in the previous section.

  2. The owning package should also provide a program that the other packages may use to modify the configuration file.

  3. The related packages must use the provided program to make any desired modifications to the configuration file. They should either depend on the core package to guarantee that the configuration modifier program is available or accept gracefully that they cannot modify the configuration file if it is not. (This is in addition to the fact that the configuration file may not even be present in the latter scenario.)

Sometimes it’s appropriate to create a new package which provides the basic infrastructure for the other packages and which manages the shared configuration files. (The sgml-base package is a good example.)

If the configuration file cannot be shared as described above, the packages must be marked as conflicting with each other. Two packages that specify the same file as a conffile must conflict. This is an instance of the general rule about not sharing files. Neither alternatives nor diversions are likely to be appropriate in this case; in particular, dpkg does not handle diverted conffiles well.

When two packages both declare the same conffile, they may see left-over configuration files from each other even though they conflict with each other. If a user removes (without purging) one of the packages and installs the other, the new package will take over the conffile from the old package. If the file was modified by the user, it will be treated the same as any other locally modified conffile during an upgrade.

The maintainer scripts must not alter a conffile of any package, including the one the scripts belong to.

10.7.5. User configuration files (“dotfiles”)

The files in /etc/skel will automatically be copied into new user accounts by adduser. No other program should reference the files in /etc/skel.

Therefore, if a program needs a dotfile to exist in advance in $HOME to work sensibly, that dotfile should be installed in /etc/skel and treated as a configuration file.

However, programs that require dotfiles in order to operate sensibly are a bad thing, unless they do create the dotfiles themselves automatically.

Furthermore, programs should be configured by the Debian default installation to behave as closely to the upstream default behavior as possible.

Therefore, if a program in a Debian package needs to be configured in some way in order to operate sensibly, that should be done using a site-wide configuration file placed in /etc. Only if the program doesn’t support a site-wide default configuration and the package maintainer doesn’t have time to add it may a default per-user file be placed in /etc/skel.

/etc/skel should be as empty as we can make it. This is particularly true because there is no easy (or necessarily desirable) mechanism for ensuring that the appropriate dotfiles are copied into the accounts of existing users when a package is installed.