From ec6684b9fe20ff5bfc411d576968246de5ad5286 Mon Sep 17 00:00:00 2001 From: TheHefty Date: Mon, 10 Aug 2026 17:46:02 +0000 Subject: [PATCH] fix(docker): give rootlesskit a port driver, so -p means something MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `docker run -p` published nothing. `docker port` reported 0.0.0.0: and no connection succeeded, not even from inside this container on 127.0.0.1 — because RootlessKit defaults --port-driver to `none`, which maps the port inside its own namespace and forwards it nowhere. The flag normally arrives with dockerd-rootless.sh, which passes it explicitly. This image cannot use that script — docker-ce-rootless-extras is unavailable, as core/Dockerfile.frag section 1 records — so the invocation was reimplemented by hand and the flag was the piece that got lost. Everything else was right: slirp4netns is installed, networking works, containers run. The comment above the invocation asserted the opposite, naming Testcontainers as a consumer that reaches a published port this way. Nothing had ever exercised it. No isolation is traded for this. The host socket is still not mounted, no privilege is added, the user namespace is unchanged. It turns on forwarding for ports of containers this daemon already creates — exactly the capability the file already claimed to have. --disable-host-loopback is orthogonal and stays: it blocks a nested container dialling into its parent, not the parent reaching a published port. Unverified: proving it needs an image rebuild and a container restart. The reproduction is `docker run -d -p 15432:5432 postgres:18-alpine` followed by a TCP connect to 127.0.0.1:15432 from this container. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01TjvhhztqTYoQhJcJTgXdRb --- core/services/svc-dockerd-rootless/run | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/core/services/svc-dockerd-rootless/run b/core/services/svc-dockerd-rootless/run index b428035..cc68723 100644 --- a/core/services/svc-dockerd-rootless/run +++ b/core/services/svc-dockerd-rootless/run @@ -66,15 +66,25 @@ fi export HOME=/config +# --port-driver is what makes `docker run -p` mean anything. RootlessKit +# defaults it to `none`, and with `none` a published port is mapped inside +# RootlessKit's namespace and forwarded nowhere: `docker port` reports +# 0.0.0.0: and nothing listens, even from this container. The usual source +# of the flag is `dockerd-rootless.sh`, which passes it explicitly and which this +# image cannot use (docker-ce-rootless-extras is unavailable — see +# core/Dockerfile.frag section 1), so reimplementing the invocation by hand +# dropped it. `builtin` is what that script defaults to and is the faster of the +# two; `slirp4netns` is the fallback if a workload needs the source IP preserved. +# # --disable-host-loopback stops containers created by this daemon from reaching # 127.0.0.1 in *this* container's network namespace (rootlesskit warns if it's -# left off). Publishing still works in the direction that's actually needed — -# a nested container's published port lands on this container's loopback, which -# is how Testcontainers and compose consumers reach it — this only blocks the -# reverse, a nested container dialling back into its parent. +# left off). It is orthogonal to the above and stays: it blocks a nested +# container dialling back into its parent, not the parent reaching a published +# port. exec s6-setuidgid abc \ rootlesskit \ --net=slirp4netns \ + --port-driver=builtin \ --mtu=65520 \ --disable-host-loopback \ --copy-up=/etc \