Why might virtualisation.docker.listenOptions have no effect?

As described here and here it should be possible to use NixOS config entries to have Docker listen on more than the default UNIX socket. I used

virtualisation.docker.listenOptions = [
  # Variant 1
  # "tcp://127.0.0.1:1234" "unix:///run/mysock"
  # Variant 2
  "127.0.0.1:1234" "/run/mysock"
];

in my configuration.nix, but neither syntax variant has any noticable effect. The generated daemon.json file used by docker.service always looks like this:

{
  "data-root": "/opt/local/docker/data-root",
  "experimental": true,
  "fixed-cidr-v6": "fd00::/80",
  "group": "docker",
  "hosts": [
    "fd://"
  ],
  "ipv6": true,
  "live-restore": false,
  "log-driver": "json-file",
  "log-opts": {
    "max-file": "5",
    "max-size": "20m"
  },
  "metrics-addr": "localhost:9323",
  "userland-proxy": false
}

My settings should be added to hosts, I think, but no dice. I found no mention of this, neither on the issues section nor in this forum, nor via Internet searches, so I thought it best to ask here what I might be doing wrong?

Your help is appreciated.

1 Like

Hey @rseichter,

I spotted the same issue and reported it here: docker: listenOptions doesn't take effec · Issue #383904 · NixOS/nixpkgs · GitHub

Looking at the module, it will not reconfigure the docker demon, but the socket unit that handles the activation of the docker demon.

I expect systemd to do the appropriate things to macke docker reachable under the mentioned destinations.

I am not exactly sure how to read your comment, @NobbZ . Are you saying that the sockets I configured should be available despite their absence in daemon.json? I see neither an open TCP port nor a UNIX socket file.

Please check the docker.socket unit.

What does it say?

# /etc/systemd/system/docker.socket
[Unit]
Description=Docker Socket for the API

[Socket]
# If /var/run is not implemented as a symlink to /run, you may need to
# specify ListenStream=/var/run/docker.sock instead.
ListenStream=/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target

# /nix/store/mf6zrpdsmv672253vhk63pdg2m10kp7p-system-units/docker.socket.d/overrides.conf
[Unit]
Description=Docker Socket for the API

[Socket]
ListenStream=tcp://127.0.0.1:1234
ListenStream=unix:///run/mysock
SocketGroup=docker
SocketMode=0660
SocketUser=root

[Install]
WantedBy=sockets.target

So that’s where my settings ended up. Like I mentioned, neither of my additions seems to have a visible effect, even after rebooting. I don’t expect to be required to enable some other service, or do I?

@NobbZ I don’t mean to be a bother, but I still cannot access Docker via TCP socket. If there is anything I can try (or need to change), please let me know.

Works for me…

I had to systemctl restart docker.service once though, as sockets aren’t restarted do not drop existing connections usually.

$ DOCKER_HOST=127.0.0.1:1234 docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED       STATUS       PORTS                                       NAMES
3290fa8a2258   codeberg.org/readeck/readeck:latest   "/bin/readeck serve …"   5 weeks ago   Up 5 weeks   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp   xenodochial_easley
fb783743686d   postgres:17.2-alpine                  "docker-entrypoint.s…"   5 weeks ago   Up 5 weeks   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   your-things-postgres-1

A few minutes ago it worked on my machine for the first time. As mentioned in this issue, I was finally able to establish a connection using nc. That’s a great relief. I don’t understand why yet another reboot resolved the issue at last, but perhaps my manual restarting of services during the course of my tests caused problems for systemd.

Solution for the time being: Make sure to manually execute

systemctl restart docker.socket

when making changes to listenOptions. Whether or not nixos-rebuild switch should take care of this automatically is debatable. If all else fails, try to reboot the system to give systemd a clean slate.