Thank you for taking the time to ensure that your package is working fine with systemd.

Creating service files

When creating systemd service files, consider enabling the features detailed in ServiceSandboxing and this presentation (slides) to better enhance the security of Debian as a whole.

Using debhelper with dh_systemd

New in debhelper compat 10 is that dh-systemd is now automatically enabled if you're using dh sequencer!

For older debhelper compat levels or non-dh use:

  1. Add Build-Depends on dh-systemd (>= 1.5)

  2. If you are using dh(1), add the systemd addon via dh --with systemd in your debian/rules. This will run the dh_systemd_enable(1) and dh_systemd_start(1) helpers at the correct time during build. You can use the known override mechanism to specify custom options for those commands. Please refer to their man pages for the list of available options.

  3. If you are using plain debhelper, make sure to run dh_systemd_enable *before* dh_installinit and dh_systemd_start *after* dh_installinit
  4. If you are using cdbs, make sure you are using version (>= 0.4.123)

After rebuilding, your package will have additional code in the postinst, prerm and postrm maintainer scripts. A careful look at that code cannot hurt.


These examples might be helpful to look at when using dh-systemd in your package:

systemd unit files naming and installation

When you are installing a systemd service file alongside of your SysV init script, you should name it correspondingly. E.g. for /etc/init.d/apache2 the corresponding service file should be named /lib/systemd/system/apache2.service. This way, systemd will automatically prefer the native service file over the SysV init script and use that to start the service. If the names do not match, say your service file is provided by upstream and named NetworkManager.service and your existing SysV init script is called /etc/init.d/network-manager, you can either rename one of the two or you simply use a symlink shipped statically in the package. You can use a .links file to create such a symlink. The network-manager package e.g. ships a debian/network-manager.links containing

lib/systemd/system/NetworkManager.service lib/systemd/system/network-manager.service

It is not recommended to create such an alias dynamically via


The reason for that is, that as soon as the service is disabled, this symlink would be removed and the name matching would no longer work.

If your service file is not provided by upstream and you ship it as part of your debian package, name it debian/$pkg.service and dh_installinit will install it to the correct location. For more information please refer to the dh_installinit(1) man page.

Verifying systemd units

Use the systemd-analyze verify command to verify your unit is valid.

overriding options and /etc/default handling

If you want to retain backwards compatibility with options defined in /etc/default/foo files, you will need to configure special shims in your systemd.service file. For example, assuming you were defining options in /etc/default/foo like this:

OPTIONS="-d debug"

You could change your service file to read this and call the daemon with those options:

ExecStart=/usr/bin/foo ${OPTIONS}

Note the - which means that the service will not fail if the EnvironmentFile is missing. It seems to be possible to specify multiple files, but it is unclear how they are prioritised.

Note that it is preferable to configure options using native systemd mechanisms for new packages, the above is only for backwards compatibility. New packages should advise their users to override the ExecStart line by dropping a file like this in /etc/systemd/system/foo.service.d/local.conf:

ExecStart=/usr/bin/foo -d debug

Note how only those three lines are necessary, as the unit files are merged together. The '?ExecStart=' is required to override ?ExecStart, without it systemd will attempt to use both the new and original ?ExecStart lines which is only allowed for Type=oneshot services.

Users can also install a complete unit file to /etc/systemd/system/foo.service. Systemd then uses it instead of /lib/systemd/system/foo.service.

socket and D-Bus activated services

For socket and D-Bus activated services we recommend to use --restart-after-upgrade if your daemon supports that. If your daemon uses the default behaviour (stop in prerm, start in postinst), mask the .service file, so the service is not started on incoming requests while the upgrade is ongoing.

TODO: Add code snippets

Avoid Accept=yes in .socket files

Avoid using Accept=yes in .socket files, because service(8) cannot stop that service correctly. E.g. you have approx.socket and approx@.service, which gets expanded to approx@1-::1:9999-::1:44903.service, then service approx stop will not work.


In case you are missing some information, please contact pkg-systemd-maintainers via IRC in #debian-systemd on or via email at

We will update this wiki page with the answers to frequently asked questions.