Disabling systemd services and delete socket?

8 days ago I opened this issue. I’ve found the solution but I don’t know how to apply it the “NixOS way.”

The problem is that the Docker daemon is still running as root, as well as my containers:

$ docker ps
NAMES     IMAGE     STATUS    PORTS

$ docker context list
NAME        DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default *   Current DOCKER_HOST based configuration   unix:///run/user/1000/docker.sock
Warning: DOCKER_HOST environment variable overrides the active context. To use a context, either set the global --context flag, or unset DOCKER_HOST environment variable.

$ unset DOCKER_HOST

$ docker ps
NAMES         IMAGE                                          STATUS          PORTS
<containers listed correctly here>

$ docker context list
NAME        DESCRIPTION                               DOCKER ENDPOINT               ERROR
default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock

I suspect that this is a bug after changing from a rootfull to rootless Docker installation in configuration.nix.

The solution is to disable the system-wide Docker daemon:

$ sudo systemctl disable --now docker.service docker.socket
$ sudo rm /var/run/docker.sock

But how do I do this declaratively, in the way NixOS intended? Because:

$ sudo systemctl disable --now docker.service docker.socket
Failed to disable unit: File /etc/systemd/system/multi-user.target.wants/docker.service: Read-only file system

I am able to delete var/run/docker.sock though.

Relevant parts of my configuration.nix:

{
  environment.systemPackages = with pkgs; [
    docker
  ];

  virtualisation.docker = {
    enable = true;
    rootless = {
      enable = true;
      setSocketVariable = true;
    };
  };
}

How do I disable this service, considering that I don’t have Docker defined to be ran as root in my configuration.nix?

You can disable any systemd service with systemd.services.<name>.enable.

The NixOS name of the Docker service is something you can find by looking at a virtualisation.docker option, clicking the ‘Declared in’ link, and scrolling down to the config section to where it adds something to systemd.services. Naturally, in this case, that name is docker, but you’ll also see a docker-prune service there that you may or may not care about.

2 Likes

@rhendric is correct, but unless I’m mistaken you can also just instead of the above:

virtualisation.docker.rootless = {
  enable = true;
  setSocketVariable = true;
};

I.e., the rootless module doesn’t depend at all on the rootful top-level, you’re basically explicitly enabling rootful docker in addition to rootless docker currently.

Adding docker to your systemPackages is also unnecessary and potentially breaks the module, since the module adds the package defined in its option already: nixpkgs/nixos/modules/virtualisation/docker-rootless.nix at 706eef542dec88cc0ed25b9075d3037564b2d164 · NixOS/nixpkgs · GitHub

2 Likes

Thanks @rhendric, your solution worked.

But ohhh I didn’t think of this at all. Thanks @TLATER.

How can I know when to add something to systemPackages and when not to?

Try the command after you enable a related module before explicitly adding its package, I guess. Or checking the source every time. Sadly no better way afaik.

1 Like