Systemd Examples – Why Include WantedBy=multi-user.target

systemd

I have read what is multi-user.target and the systemd documentation, which states that the multi-user.target is a special target. Further, a lot of the systemd examples contain that line.

  1. Why do so many example services contain that line?
  2. What would happen if they did not contain WantedBy=multi-user.target?
  3. Could you give me an example of when it would actually be advisable to not include that line in a service file definition?
  4. Along the same lines, when is it a good idea to keep that line in?

Best Answer

1.) multi-user.target is basically the closest equivalent of classic SysVinit runlevel 3 that systemd has. When a systemd system boots up, systemd is trying to make the system state match the state specified by default.target - which is usually an alias for either graphical.target or multi-user.target.

multi-user.target normally defines a system state where all network services are started up and the system will accept logins, but a local GUI is not started. This is the typical default system state for server systems, which might be rack-mounted headless systems in a remote server room.

graphical.target is another possible alias for default.target. Normally it's defined as a superset of the multi-user.target: it includes everything the multi-user.target does, plus the activation of a local GUI login. So kind of like runlevel 5 in classic SysVinit.

The line WantedBy=multi-user.target in a service is essentially the same as specifying "this service should start in runlevels 3, 4 and 5" in SysVinit systems: it tells systemd that this service should be started as part of normal system start-up, whether or not a local GUI is active.

However, WantedBy is separate from the enabled/disabled state: so in another sense, it's sort of a "preset": it determines under what conditions the automatic start may happen, but only when the service is enabled in the first place.

2.) if you omit the WantedBy=multi-user.target line and no other enabled service includes a Requires=your.service or Wants=your.service in its service definition, your service will not be started automatically.

systemd works on dependencies, and at boot time, if nothing Requires or Wants your service, it won't be started even if the service is enabled.

Sure, you could edit your default.target to add or delete Requires or Wants lines for any services you want started at boot time - but so that you can just drop a new service file into the system and have it work by default (which makes things very easy for software package managers), systemd has the WantedBy and RequiredBy keywords which can be used to insert Wants and Requires-type dependencies (respectively) from "the other end".

3.) You should omit the line if you don't want the service to be ever started automatically at boot time, or this service is a part of a chain of dependencies you've defined explicitly.

For example, you might be refactoring server application A and for some reason or another decide to split some optional functionality off it into a separate service B, to allow the user the choice of not installing it if it isn't needed. You could then make service B a separate service-B.rpm, and define B.service with WantedBy=A.service to make systemd start up service B automatically whenever service A is started - but only when service-B.rpm is actually installed.

Note that a Wants or WantedBy only says that the system should startup one service whenever another service or target is also started, but it specifies nothing at all about the startup/shutdown order. If you need service B to be already running when service A starts up, you'd need to add Before=A.service in the B.service file to explicitly specify the start-up order dependency.

4.) Anytime you do want the service to have the capability of being started automatically at boot time, and there are no other dependencies already defined.

Related Question