Syncthing systemd user service

Hi!

I installed syncthing using environment.systemPackages. Now, I activated the user service with systemctl --user enable syncthing. The unit file points from /home/dominik/.config/systemd/user/syncthing.service to /nix/store/g58lgbm249z9dns1rillgqg3r6bkpmnx-syncthing-1.12.1/share/systemd/user/syncthing.service.

Everything is working fine. I am just worried what is going to happen, when I update my system, and the store path changes. Is there a canoncial way to link to the systemd unit of the latest (current) version?

Thank you!

3 Likes

Probably something like this should work

ln -sf ~/.config/systemd/user/syncthing.service /run/current-system/sw/share/syncthing/systemd/user/syncthing.service
cp ~/.config/systemd/user/syncthing.service ~/.config/systemd/user/default.target.wants/

(I just guessed the path, but the same things is working for me with systemd-tmpfiles user units)

You can also checkout home-manager, it has a syncthing service module. But the first comment is the direct solution to you’re problem.

2 Likes

Did you manually create a symlink from ~/.config/systemd/user/syncthing.service to the store version of the service file? I would expect that systemctl enable can find the relevant service file directly in the store on its own.

As a different approach I wrote some custom user units for systemd in the systemd.user.services config attribute. They get updated and restarted (as needed) when doing a system update.

As user, I typed systemctl --user enable syncthing. This command created the mentioned symlink. I just don’t know how systemd knows when I upgrade the channel and rebuild the config, then the link should change, shouldn’t it? Is there a service taking care of this?

Further, I had a look at home manager, and I use it now to manage the user services. I had the impression that home manager is a GUI to manage the config files, but the declarative configuration suits my needs very well.

Thank you for your replies!

EDIT: Actually, home manager is my only real option, because i was not able to configure dunst (the icon path is hard coded and keeps changing). But maybe I am just not knowledgable enough to understand the paths of NixOS, yet.

systemctl --user is fundamentally broken on NixOS by design, see also https://github.com/NixOS/nixpkgs/issues/108643

There is also no “service” or anything similar to update the links that systemd creates for user units. Luckily systemd configures units by placing symlinks, so it is easy enough to configure user units by just setting up those links manually as explained in my first comment.

Another alternative is to set up user services in configuration.nix but that means that the run for every user with a login shell including root! Since root generally doesn’t have a graphical login you could configure dunst in configuration.nix as follows:

{
  systemd.user.services."dunst" = {
    description = "Dunst notification daemon";
    documentation = [ "man:dunst(1)" ];
    wantedBy = [ "graphical-session.target" ];
    partOf = [ "graphical-session.target" ];
    serviceConfig = {
      Type = "dbus";
      BusName = "org.freedesktop.Notifications";
      ExecStart = "${pkgs.dunst}/bin/dunst";
    };
  };
}

I personally don’t understand why you don’t follow what NixOS already provides:

nixos-option services.syncthing

I use it to declaratively describe what and where I want to synchronize directories and even it allows to specify which version of syncthing to use for it.

1 Like

I use services.syncthing but I changed the user and group so that it matches my login account. It works fine.

1 Like

I think home-manager is the way to go and I’m looking forward more synergy between nixpkgs and home-manager.

1 Like

I agree. Syncthing is, at least to me, a user service, and not a system service. I have many shared directories distributed across my home directory. I run Syncthing on different machines, for some I don’t even have superuser permissions and want to use the same setup. But maybe I am missing something… Please let me know!

2 Likes

One consideration is that the home-manager syncthing service doesn’t seem to support declarative configuration, whereas the nixos syncthing service does. Therefore, I think I’m going to try @emmanuelrosa 's approach.

Yes, I learned from this, that home-manager only provides:

services.syncthing.enable = true;

which in contrast to NixOS doesn’t allow declarative configuration of the service. This was the reason that I was going the NixOS route with this. Looking at home-manager/modules/services/syncthing.nix at master · nix-community/home-manager · GitHub, I see it gets some touches here and there.

systemctl --user is fundamentally broken on NixOS by design

I don’t see what you mean by this: user services works perfectly fine under NixOS and issue #108643 is unrelated to them.

The only problem is that if you do systemctl --user enable the link generated by systemd will break when the store path of the unit changes. Instead you can do what the manual suggests: manually link the unit using the /run/current-system path.

In a more general context: What is the stance of NixOS towards “user services”, i.e., services that are primarily run by users and not by the system? Shouldn’t there be a more general separation between those? Maybe, as a (NixOS) user, I want to change my user configuration, but the system configuration is managed by somebody else?

What is the stance of NixOS towards “user services”

I don’t think there is one.

As far as I can tell, NixOS currently provides user units from upstream files (ready to be installed) or services that will share the same settings across all users (either enabled by default or on-demand). home-manager allows users to configure multiple instances of a service independently.

There is quite a bit of duplication between home-manager and NixOS, but I don’t think it’s possible to just merge them because NixOS targets Linux and only supports systemd. Also, home-manager still a community (experimental?) project.

But this implies that you can have syncthing only for one single user, right?

edit: no, you can of course just define multiple services, one per user.

No, the NixOS module will configure a single system-wide service.
You can run as your user, but still one instance only.

I suppose you could run multiple user services simultaneuously, but I have never tried. You probably have to change the port numbers or listen on different addresses, though.

Correct. You can use the home-manager syncthing module to configure the per-user instances, too, if you want (including the different listening ports/addresses). There are some awkward differences between the way the nixos and hm modules are configured, though. I’m not really sure which way is better, but they’re not transplantable configs.

As of somewhat recently, there’s a third option that might be useful in some circumstances. Syncthing now has the ability to sync file ownerships, though it needs to be running with permissions to set file ownerships of course. This is a per-share property, but as yet the nixos module doesn’t have a config entry for it.