Home Explore Blog CI



nixpkgs

3rd chunk of `nixos/doc/manual/administration/service-mgmt.chapter.md`
c58055263acde87ece478c1c1196e5b173c3e3df0efd10f30000000100000c20
`environment.systemPackages` doesn't make the service available to
users or the system.

In order to enable a systemd *system* service with provided upstream
package, use (e.g):

```nix
{
  systemd.packages = [ pkgs.packagekit ];
}
```

Usually NixOS modules written by the community do the above, plus take
care of other details. If a module was written for a service you are
interested in, you'd probably need only to use
`services.#name#.enable = true;`. These services are defined in
Nixpkgs' [ `nixos/modules/` directory
](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules). In case
the service is simple enough, the above method should work, and start
the service on boot.

*User* systemd services on the other hand, should be treated
differently. Given a package that has a systemd unit file at
`#pkg-out#/lib/systemd/user/`, using [](#opt-systemd.packages) will
make you able to start the service via `systemctl --user start`, but it
won't start automatically on login. However, You can imperatively
enable it by adding the package's attribute to
[](#opt-systemd.packages) and then do this (e.g):

```ShellSession
$ mkdir -p ~/.config/systemd/user/default.target.wants
$ ln -s /run/current-system/sw/lib/systemd/user/syncthing.service ~/.config/systemd/user/default.target.wants/
$ systemctl --user daemon-reload
$ systemctl --user enable syncthing.service
```

If you are interested in a timer file, use `timers.target.wants` instead
of `default.target.wants` in the 1st and 2nd command.

Using `systemctl --user enable syncthing.service` instead of the above,
will work, but it'll use the absolute path of `syncthing.service` for
the symlink, and this path is in `/nix/store/.../lib/systemd/user/`.
Hence [garbage collection](#sec-nix-gc) will remove that file and you
will wind up with a broken symlink in your systemd configuration, which
in turn will not make the service / timer start on login.

## Template units {#sect-nixos-systemd-template-units}

systemd supports templated units where a base unit can be started multiple
times with a different parameter. The syntax to accomplish this is
`service-name@instance-name.service`. Units get the instance name passed to
them (see `systemd.unit(5)`). NixOS has support for these kinds of units and
for template-specific overrides. A service needs to be defined twice, once
for the base unit and once for the instance. All instances must include
`overrideStrategy = "asDropin"` for the change detection to work. This
example illustrates this:
```nix
{
  systemd.services = {
    "base-unit@".serviceConfig = {
      ExecStart = "...";
      User = "...";
    };
    "base-unit@instance-a" = {
      overrideStrategy = "asDropin"; # needed for templates to work
      wantedBy = [ "multi-user.target" ]; # causes NixOS to manage the instance
    };
    "base-unit@instance-b" = {
      overrideStrategy = "asDropin"; # needed for templates to work
      wantedBy = [ "multi-user.target" ]; # causes NixOS to manage the instance
      serviceConfig.User = "root"; # also override something for this specific instance
    };
  };
}
```

Title: Enabling User Systemd Services and Template Units in NixOS
Summary
This section details how to enable user systemd services in NixOS, explaining that simply adding a package to `systemd.packages` won't automatically start it on login. It provides a method to create symlinks in the user's systemd configuration to ensure services start after login and are not affected by garbage collection. Additionally, it covers the use of systemd template units in NixOS, explaining the syntax for defining base units and instances, and emphasizing the need for `overrideStrategy = "asDropin"` for change detection.