Disable a systemd service while having it in NixOS's conf

Hi!
I’ve been using NixOS for 6 months now, and I’m stuck with this issue:
On my desktop, I may use LXD, libvirtd, docker, nginx, postgresql, etc. for development purposes.
I don’t want their services to be started on boot, but they need for example virtualisation.lxd.enable = true; to have active configurations (i.e reside in the current profile).
I tried for example systemd.services.lxd.wantedBy = [];, but it doesn’t change the option neither it stops the service:

$ nixos-option systemd.services.lxd.wantedBy
Value:
[ "multi-user.target" ]

How can I achieve this?
I think it’s a common pattern for desktop users.
I partially solve this using for example

  specialisation = {
    # An nginx that serves the video folder
    withNginx.configuration = {
      imports = [ ./nginx.nix ];
    };
  };

But specialisations are painful to use.
For reference, on debian I installed Nginx and then did systemctl disable nginx and launched systemctl start nginx whenever I needed it.

Thanks for reading!

2 Likes

Someone told me about this method and it works.

systemd.services."<service-name>".wantedBy = lib.mkForce [ ];
2 Likes

NixOS module system merges lists by default so if you set an option to [], that will just be a no-op. You can override the default semantics by using lib.mkForce [] instead.

Note that service configuration does not need to come from NixOS options – you can also load upstream .service files through systemd.packages option. Those options will not have values visible to nixos-option and slightly different rules apply to overriding them. Importantly, the systemd.services.<name>.* NixOS options are implemented using systemd overrides so you will need to follow systemd rules for overriding. Most notably:

  • Some options like ExecStart= accept multiple values and to clear them, you need to add an empty string [ "" ]
  • Dependencies ( After= , etc.) cannot be reset to an empty list at all, other than by overriding the entire unit
  • Similar for WantedBy= and other options from [Install] section but those are not currently supported so they will be defined using NixOS option and easily overridable.
7 Likes

Thanks for your answers.
For reference, here are the options I added to disable the services:

  systemd.services.nginx.wantedBy = lib.mkForce [];
  systemd.services.nginx-config-reload.wantedBy = lib.mkForce [];

  systemd.services.libvirtd.wantedBy = lib.mkForce [];
  systemd.services.libvirt-guests.wantedBy = lib.mkForce [];

  systemd.services.docker.wantedBy = lib.mkForce [];

  systemd.services.lxd.wantedBy = lib.mkForce [];

libvirtd, docker and lxd can be activated by their sockets, so a docker ps for instance launches the daemon.

5 Likes