Systemd Unit Files – Best Practices for Wants= vs WantedBy=

systemdsystemd-unit

As far as I can tell from the documentation of systemd, Wants= and WantedBy= perform the same function, except that the former is put in the dependent unit file and vice-versa. (That, and WantedBy= creates the unit.type.wants directory and populates it with symlinks.)

From DigitalOcean: Understanding Systemd Units and Unit Files:

The WantedBy= directive… allows you to specify a dependency relationship in a similar way to the Wants= directive does in the [Unit] section. The difference is that this directive is included in the ancillary unit allowing the primary unit listed to remain relatively clean.

Is it really just about keeping a unit file "clean"? What is the best practice for using these two directives? That is, if service alpha "wants" service beta, when should I use Wants=beta.service in alpha.service and when should I prefer WantedBy=alpha.service in the beta.service?

Best Answer

Functionally

Wants is in the Unit section and WantedBy is in the Install.

The init process systemd does not process/use the Install section at all. Instead, a symlink must be created in multi-user.target.wants. Usually, that's done by the utility systemctl which does read the Install section.

In summary, WantedBy is affected by systemctl enable/systemctl disable.

Logically

Consider which of the services should "know" or be "aware" of the other. For example, a common use of WantedBy:

[Install]
WantedBy=multi-user.target

Alternatively, that could be in multi-user.target:

[Unit]
Wants=nginx.service

But that second way doesn't make sense. Logically, nginx.service knows about the system-defined multi-user.target, not the other way around.

So in your example, if alpha's author is aware of beta, then alpha Wants beta. If beta's author is aware of alpha then beta is WantedBy alpha.

To help you decide, you may consider which service can be installed (say, from a package manager) without the other being present.

Config directories

As another tool in your box, know that systemd files can also be extended with config directories: /etc/systemd/system/myservice.service.d/extension.conf

This allows you to add dependencies where neither service is originally authored to know about the other. I often use this with mounts, where (for example) neither nginx nor the mount need explicit knowledge of the other, but I as the system adminstrator understand the dependency. So I create nginx.service.d/mymount.conf with Wants=mnt-my.mount.

Related Question