Jump to content

Systemd/User Services: Difference between revisions

From Official NixOS Wiki
Modified NixOS Search link to not specify channel=unstable. This way the default option for the website will be selected, which should usually be the latest default NixOS channel. Might be more in tune with user expectancy, as people using unstable are advanced enough to select the channel manually
Crasm (talk | contribs)
Added section clarifying linger settings and systemd's user management service
 
(7 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{Systemd/breadcrumb}}
<translate>
<!--T:1-->
Systemd supports running a separate instance of systemd for a given user, allowing the user to control their own services. See here for more information: https://wiki.archlinux.org/title/Systemd/User
Systemd supports running a separate instance of systemd for a given user, allowing the user to control their own services. See here for more information: https://wiki.archlinux.org/title/Systemd/User


<!--T:2-->
In NixOS, a user service can be expressed with {{ic|systemd.user.services.<name>}}, as documented here: https://search.nixos.org/options?query=systemd.user.services
In NixOS, a user service can be expressed with {{ic|systemd.user.services.<name>}}, as documented here: https://search.nixos.org/options?query=systemd.user.services


<!--T:3-->
This may be useful if you want a user to be able to start, stop, and restart their own instance of a service without needing to make the user a sudoer.
This may be useful if you want a user to be able to start, stop, and restart their own instance of a service without needing to make the user a sudoer.


<!--T:4-->
Here is an example:
Here is an example:
</translate>


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 20: Line 28:
</syntaxhighlight>
</syntaxhighlight>


<translate>
<!--T:6-->
By default, user services will be stopped when the user logs out and will start again when the user logs back in due to us setting {{ic|<nowiki>wantedBy = [ "default.target" ]</nowiki>}} in the example.
By default, user services will be stopped when the user logs out and will start again when the user logs back in due to us setting {{ic|<nowiki>wantedBy = [ "default.target" ]</nowiki>}} in the example.


== Keeping user services running after logout ==
== Enabling the user management service and user process lingering == <!--T:7-->
 
Without the user management unit {{ic|user@.service}}, commands such as {{ic|systemctl --user}} will fail, and configured options under {{ic|systemd.user}} will not take effect. This is typically observed on minimal systems without a desktop environment.
 
When lingering is enabled for a user, the user management service is spawned at boot and can run services independently of the user's session, including keeping services running after a user logs out.
 
<!--T:8-->
You can enable "[https://search.nixos.org/options?channel=unstable&show=users.users.%3Cname%3E.linger&from=0&size=50&sort=relevance&type=packages&query=users.users.%3Cname%3E.linger lingering]" by setting {{ic|<nowiki>users.users.<username>.linger = true;</nowiki>}} or running {{ic|sudo loginctl enable-linger [USER...]}}.
 
<!--T:9-->
For a user service to start at boot, change the service configuration to {{ic|<nowiki>wantedBy = [ "multi-user.target" ];</nowiki>}}.
 
== Enabling a service for specific users == <!--T:10-->
 
<!--T:11-->
By default, enabling a user service enables it for every user for which systemd spawns a service manager. If you wish for the service to be run only for specific users (say, {{ic|<nowiki>UserA</nowiki>}} and {{ic|<nowiki>UserB</nowiki>}}), use {{ic|<nowiki>ConditionUser</nowiki>}} ({{ic|<nowiki>man 5 systemd.unit</nowiki>}}):
</translate>
 
<syntaxhighlight lang="nix">
systemd.user.services.my-cool-user-service = {
  unitConfig.ConditionUser = "UserA|UserB";
};
</syntaxhighlight>
 
<translate>
<!--T:12-->
Likewise, you can also disable a service for a specific user:
</translate>
 
<syntaxhighlight lang="nix">
systemd.user.services.my-cool-user-service = {
  unitConfig.ConditionUser = "!root";
};
</syntaxhighlight>
 
<translate>
== Usage == <!--T:13-->
 
<!--T:14-->
To interact with user-specific systemd services, use the <code>--user</code> flag with the <code>systemctl</code> command. For example, to check the status of a user service:
</translate>
 
<syntaxhighlight lang="console"> $ systemctl --user status my-cool-user-service </syntaxhighlight>
 
<translate>
<!--T:15-->
To view logs for a specific user service, use <code>journalctl</code> with the <code>--user-unit</code> option:
</translate>
 
<syntaxhighlight lang="console"> $ journalctl --user-unit my-cool-user-service </syntaxhighlight>
 
<translate>
<!--T:16-->
To list all active user units:
</translate>


If you need a user service to stay running after a user logs out, you need to enable "[https://search.nixos.org/options?channel=unstable&show=users.users.%3Cname%3E.linger&from=0&size=50&sort=relevance&type=packages&query=users.users.%3Cname%3E.linger lingering]" by setting {{ic|<nowiki>users.users.<username>.linger = true;</nowiki>}}
<syntaxhighlight lang="console"> $ systemctl --user list-units </syntaxhighlight>  


You'll also likely want to change to {{ic|<nowiki>wantedBy = [ "multi-user.target" ];</nowiki>}} so the service starts at boot time.
<translate>
<!--T:17-->
[[Category:systemd]]
[[Category:systemd]]
</translate>

Latest revision as of 08:28, 10 December 2025

Systemd supports running a separate instance of systemd for a given user, allowing the user to control their own services. See here for more information: https://wiki.archlinux.org/title/Systemd/User

In NixOS, a user service can be expressed with systemd.user.services.<name>, as documented here: https://search.nixos.org/options?query=systemd.user.services

This may be useful if you want a user to be able to start, stop, and restart their own instance of a service without needing to make the user a sudoer.

Here is an example:

systemd.user.services.my-cool-user-service = {
  enable = true;
  after = [ "network.target" ];
  wantedBy = [ "default.target" ];
  description = "My Cool User Service";
  serviceConfig = {
      Type = "simple";
      ExecStart = ''/my/cool/user/service'';
  };
};

By default, user services will be stopped when the user logs out and will start again when the user logs back in due to us setting wantedBy = [ "default.target" ] in the example.

Enabling the user management service and user process lingering

Without the user management unit user@.service, commands such as systemctl --user will fail, and configured options under systemd.user will not take effect. This is typically observed on minimal systems without a desktop environment.

When lingering is enabled for a user, the user management service is spawned at boot and can run services independently of the user's session, including keeping services running after a user logs out.

You can enable "lingering" by setting users.users.<username>.linger = true; or running sudo loginctl enable-linger [USER...].

For a user service to start at boot, change the service configuration to wantedBy = [ "multi-user.target" ];.

Enabling a service for specific users

By default, enabling a user service enables it for every user for which systemd spawns a service manager. If you wish for the service to be run only for specific users (say, UserA and UserB), use ConditionUser (man 5 systemd.unit):

systemd.user.services.my-cool-user-service = {
  unitConfig.ConditionUser = "UserA|UserB";
};

Likewise, you can also disable a service for a specific user:

systemd.user.services.my-cool-user-service = {
  unitConfig.ConditionUser = "!root";
};

Usage

To interact with user-specific systemd services, use the --user flag with the systemctl command. For example, to check the status of a user service:

 $ systemctl --user status my-cool-user-service

To view logs for a specific user service, use journalctl with the --user-unit option:

 $ journalctl --user-unit my-cool-user-service

To list all active user units:

 $ systemctl --user list-units