When running systemctl status docker the output is Unit docker.service could not be found, as expected as I have disabled the system wide Docker daemon.
The problem is, systemctl --user status docker returns the same thing. It was returning the same thing before I tried setting virtualisation.docker.enable to false, too. systemctl --user start docker and systemctl --user enable --now docker both return Failed to start docker.service: Unit docker.service not found.
I have turned my machine off and on again after each tweak to my config and switched without any issues (tried switching with compilation error as a sanity check, everything worked as expected).
So far, the farthest I’ve gotten has just been communicating with the system wide daemon when I had it enabled before.
Okay, I checked the implementation of the module, and the way it is implemented is counterintuitive to be honest…
Anyway, given that virtualisation.docker.rootless.enable = truedocker.serviceshould exist as a user unit and systemctl --user enable docker.serviceshould find it, if you have reloaded the deamon or did a reboot.
If it really doesn’t work, please ensure that you have the file with the options actually imported correctly.
If you think it is, but it still doesn’t work, please share your config as a whole.
I can only imagine that you’re right and I am importing the options wrong somehow, I’ll include the bits of my configuration that seem relevant because I don’t really want to go through the trouble of anonymizing thoroughly ATM
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).
{ config, lib, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
...
virtualisation.docker = {
enable = false;
rootless = {
enable = true;
setSocketVariable = true;
};
# ignore this, just some random thing I tried
daemon.settings = {
userland-proxy = false;
};
};
...
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
nixpkgs.config.permittedInsecurePackages = [
"electron-33.4.11"
];
Nothing else in my configuration pertains to virtualisation.
I get a feeling it might somehow be related to when I updated to 25.05, so here’s my output from nix-channel list:
Unrelated: if you are building your system without explicitly pointing to the nixos-25.05 channel you may be still on 24.11, what does nixos-version return?
I updated my system with sudo nix-channel --update then sudo nixos-rebuild switch --upgrade and it has not changed the Docker daemon behavior after rebooting.
Unfortunately that configuration does install the docker service correctly in a VM - I can log in as test and systemctl --user status docker shows a running service. Your other configuration is doing something, we can’t really tell you what that something is without knowing what your configuration is.
If you’d like help but can’t share your configuration, you can try to produce a proper minimal reproduction of your issue with a little ad-hoc flake like that. You can build the VM with nixos-rebuild build-vm --flake .#test and then start it with ./result/bin/run-nixos-vm.
But as-is, guessing what your other configuration might be doing wrong (or correctly to trigger a NixOS bug) is kind of hard.
I’m completely at a loss here. I copied my entire configuration.nix into a vm, built it, ran it, and the docker daemon is actually working inside of it. systemctl --user status docker returns the expected output with all the information about Docker running rootless.
Here’s the flake I used:
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
outputs =
{nixpkgs, ...}:
{
nixosConfigurations.test = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({config, lib, pkgs, ... }:
{
# Bootloader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "nixos"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Configure network proxy if necessary
# networking.proxy.default = "http://user:password@proxy:port/";
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
# Enable networking
networking.networkmanager.enable = true;
# Set your time zone.
time.timeZone = [redacted]
# Select internationalisation properties.
i18n.defaultLocale = [redacted]
i18n.extraLocaleSettings = {
[redacted]
};
# Enable the X11 windowing system.
services.xserver.enable = true;
services.xserver.videoDrivers = ["nvidia"];
# Enable the GNOME Desktop Environment.
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
# Configure keymap in X11
services.xserver.xkb = {
layout = "us";
variant = "";
};
# Enable CUPS to print documents.
services.printing.enable = true;
# Pulse Audio
# services.pipewire.enable = false;
# hardware.pulseaudio = {
# enable = true;
# support32Bit = true;
# };
# Enable sound with pipewire.
services.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
jack.enable = true;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
};
# Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true;
# Define a user account. Don't forget to set a password with ‘passwd’.
users.users.test = {
isNormalUser = true;
password = "insecure";
extraGroups = [ "networkmanager" "wheel" "scanner" "lp" "audio" ];
packages = with pkgs; [
# thunderbird
discord
calibre
obsidian
libreoffice
gimp
prismlauncher
spotify
gnomeExtensions.mute-spotify-ads
crawlTiles
stremio
heroic-unwrapped
qbittorrent
protonup
wine64
protontricks
blender
yt-dlp
r2modman
];
};
# Install firefox.
programs.firefox.enable = true;
programs.direnv.enable = true;
virtualisation.docker = {
enable = false;
rootless = {
enable = true;
setSocketVariable = true;
};
daemon.settings = {
userland-proxy = false;
};
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
nixpkgs.config.permittedInsecurePackages = [
"electron-33.4.11"
];
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
# wget
gnome-terminal
nvidia-vaapi-driver
(vscode-with-extensions.override {
vscodeExtensions = with vscode-extensions; [
ms-python.python
ms-python.debugpy
ms-azuretools.vscode-docker
github.vscode-pull-request-github
eamodio.gitlens
mkhl.direnv
];
})
git
python3
hplip
valent
kdePackages.kdenlive
];
# Steam
programs.steam.enable = true;
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
# programs.gnupg.agent = {
# enable = true;
# enableSSHSupport = true;
# };
# List services that you want to enable:
# Enable the OpenSSH daemon.
# services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "24.11"; # Did you read the comment?
# OpenGL
programs.gamemode.enable = true;
hardware.graphics = {
enable = true;
# driSupport32Bit = true;
};
hardware.sane.enable = true;
hardware.sane.extraBackends = [ pkgs.hplip ];
hardware.nvidia = {
modesetting.enable = true;
open = false;
nvidiaSettings = true;
package = config.boot.kernelPackages.nvidiaPackages.latest;
};
powerManagement.enable = true;
})
];
};
};
}
Update: I think the problem lies somewhere in systemd, but I am honestly out of my depth as to what could have caused this. Any help with debugging is appreciated.
/etc/systemd/user/docker.service definitely exists as a file. I ran the command under ExecStart, which was /nix/store/fwvljmyvnkp04s3icjkrfzy2ljvs4l00-docker-27.5.1/bin/dockerd-rootless --config-file=/nix/store/yx9ksz00s1il3lrj02b 6rhg7ffja8np4-daemon.json. This started the rootless Docker service just fine and I was able to connect to it from my IDE.
So somewhere along the line, systemd has lost the ability to see the docker.service unit, despite it being located in the right place.
Edit:
Output of ls -lrt /etc/systemd/user/docker.service: lrwxrwxrwx 1 root root 78 Dec 31 1969 /etc/systemd/user/docker.service -> /nix/store/id55ykzg2c9ifc1h6h5b9yp39kdhg9lr-unit-docker.service/docker.service
Edit:
I have fixed the problem. At some point, I ran sudo nix-collect-garbage -d and it deleted some files that the docker systemd service needed, but it did not delete links that were in my ~/.config/systemd/user directory. I deleted the invalid links and it all seems to be working now. If someone knows how this could’ve happened, if it was a bug or a mistake on my part, I’d appreciate it!
Those would not have been created by NixOS; NixOS doesn’t touch $HOME. User units are created in the global paths.
You can make systemd create files with enable, mask, edit, etc. My guess would be that you ran some of these commands on accident at some point, and that with the next update that changed the path to the units in /nix/store suddenly the underlying service file disappeared, resulting in systemd seeing a broken symlink when trying to access the unit, which would override the system-wide unit but not actually work.
I think mask is the most likely culprit, though I don’t know why you woul have masked a unit either.
I did run systemd enable, the wiki entry at Docker - NixOS Wiki says to run this command: $ systemctl --user enable --now docker to enable Docker (which I didn’t run after fixing things, so it appears that it is not actually necessary, and probably shouldn’t be there as a part of the instructions)
Is it correct behavior for the Nix garbage collector to delete objects in /nix/store that still have links to them? I was under the impression it wouldn’t do that.