> **WARNING:** This document describes only the change applied in this PR. > It may already be outdated once the next PR is merged. > Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation. ## The Problem On vm4006 the rootless Docker daemon switched from the `builtin` to the `slirp4netns` port driver at a reboot on 2026-10-01; the host's configuration management had rewritten its unit a week before. With `slirp4netns`, published ports listen only on the child address of the daemon's network namespace, `10.0.2.100`, not on `localhost`. Every Testcontainers test failed with "connection refused". PR#85 let the host write the address into `docker.env`. But the address is rootlesskit's default, not a constant, and the driver can change back just as unannounced; each change would need a hand-edited configuration again. ## Non-Goals - No support for rootful daemons with unusual port setups; their defaults stay. - No change to how a build script inside the container finds the address; it reads `TESTCONTAINERS_HOST_OVERRIDE`. ## The Scenarios ### Feature: Werkator asks the daemon where it publishes ports #### Scenario#86.01: rootlesskit names the address So that the address follows the daemon, both ways, without a configuration change. - **Given** a rootless daemon whose rootlesskit API reports the `slirp4netns` port driver - **Then** the published-port host is the child address it reports - **Given** the `builtin` driver, a rootful daemon, a missing API or an unreadable answer - **Then** there is none, and the defaults apply ##### Verified by - [RootlessKitPortsTest](../../src/test/kotlin/de/hoennig/werkator/build/RootlessKitPortsTest.kt) — a real HTTP exchange over a Unix socket with vm4006's answer, the builtin driver, rootful, missing and unreadable cases - By hand on vm4006: `curl --unix-socket /run/user/10000/dockerd-rootless/api.sock http://rootlesskit/v1/info` answers as the test assumes, and `10.0.2.100:` is reachable from a host-network and from a bridge container, `host.docker.internal:` is not. #### Scenario#86.02: The build gets it as TESTCONTAINERS_HOST_OVERRIDE - **Given** a published-port host from rootlesskit - **Then** the build container gets it as `TESTCONTAINERS_HOST_OVERRIDE`, with `network: host` and on the bridge network alike - **And** an entry in `docker.env` still wins ##### Verified by - [DockerBuildRunnerTest](../../src/test/kotlin/de/hoennig/werkator/build/DockerBuildRunnerTest.kt) — both network modes, and `docker.env` winning ## The Solution `RootlessKitPorts` sends `GET /v1/info` to `dockerd-rootless/api.sock` next to the daemon socket, over a Unix domain socket channel, with a two-second limit. It takes `networkDriver.childIP` when `portDriver.driver` is `slirp4netns` and the address is IPv4, and logs a change of state once. `DockerBuildRunner` asks it on every build, for the located socket whether or not the build mounts it. No `curl` is needed on the host, and nothing is cached: a driver change takes effect at the next build. ## Additional Changes - `docs/configuration.md` and the architecture skill describe how the variable is set. - Version 1.25.0 with its release note. ## Follow-up PRs - vm4006: remove `TESTCONTAINERS_HOST_OVERRIDE` from the machine config once this runs there. - hsadmin-ng: `tools/smoke-test` reads `TESTCONTAINERS_HOST_OVERRIDE` for its own database.