Module
Core
Proposal
Microsoft ships a container runtime with WSL 2.9+ — WSL Containers, driven by the wslc CLI. It runs dockerd inside a lightweight VM, and unlike Docker Desktop or Podman it publishes no Windows named pipe and no TCP port. The only host-visible channel to the daemon is a stdio bridge:
wslc system session run docker system dial-stdio
Because none of the existing strategies can find an endpoint, Testcontainers on such a machine fails at startup with Could not find a valid Docker environment, even though a working daemon is present and wslc can talk to it. The only workaround today is to install Docker Desktop or Podman alongside, which defeats the point of having a runtime already in the OS.
I would like Testcontainers to detect this environment automatically, the same way it already detects a Docker Desktop named pipe.
Environment
- Windows 11, WSL 2.9.4
wslc from the WSL container runtime
- Testcontainers 2.0.x
Solution
A WslcSocketClientProviderStrategy in core, registered through the existing DockerClientProviderStrategy SPI, that resolves to wslc://localhost when:
- the OS is Windows, and
- the
wslc CLI is actually present (probed with wslc version, a metadata call that does not start the container VM).
Priority below NpipeSocketClientProviderStrategy, so an existing Docker Desktop or Podman pipe always wins and nothing changes for current users. wslc is only ever a fallback.
Dependency on docker-java
wslc:// is not a transport docker-java currently understands, so this cannot work on a released docker-java. That side is tracked in docker-java#2658, which proposes a wslc:// transport (a Socket whose streams are the dial-stdio child process, mirroring the existing NamedPipeSocket), plus the lifecycle handling wslc needs for host port relays and Windows-path bind mounts.
So the ordering is: docker-java gains the transport, cf docker-java/docker-java#2659 and releases a version, then Testcontainers picks it up and adds the strategy. I have the Testcontainers side working locally against a locally-built docker-java and I will raise it as a draft PR.
Benefit
WSLC support out of the box, no more need for docker or podman on Windows
Alternatives
** Keep using podman or docker
Set DOCKER_HOST=wslc://localhost manually. Works once docker-java understands the scheme, and is a reasonable escape hatch, but it means every developer and CI job on such a machine has to know to do it — which is exactly the discovery problem the strategies exist to solve.
A ~/.testcontainers.properties strategy override. Same objection, plus it has to name a class that does not exist upstream.
Reach the daemon over TCP inside the VM. Requires reconfiguring dockerd inside the WSL container VM to listen on a port and exposing it to the host — insecure, non-default, and undoes the isolation the runtime is providing.
Would you like to help contributing this feature?
Yes
Module
Core
Proposal
Microsoft ships a container runtime with WSL 2.9+ — WSL Containers, driven by the
wslcCLI. It runsdockerdinside a lightweight VM, and unlike Docker Desktop or Podman it publishes no Windows named pipe and no TCP port. The only host-visible channel to the daemon is a stdio bridge:Because none of the existing strategies can find an endpoint, Testcontainers on such a machine fails at startup with
Could not find a valid Docker environment, even though a working daemon is present andwslccan talk to it. The only workaround today is to install Docker Desktop or Podman alongside, which defeats the point of having a runtime already in the OS.I would like Testcontainers to detect this environment automatically, the same way it already detects a Docker Desktop named pipe.
Environment
wslcfrom the WSL container runtimeSolution
A
WslcSocketClientProviderStrategyin core, registered through the existingDockerClientProviderStrategySPI, that resolves towslc://localhostwhen:wslcCLI is actually present (probed withwslc version, a metadata call that does not start the container VM).Priority below
NpipeSocketClientProviderStrategy, so an existing Docker Desktop or Podman pipe always wins and nothing changes for current users.wslcis only ever a fallback.Dependency on docker-java
wslc://is not a transport docker-java currently understands, so this cannot work on a released docker-java. That side is tracked in docker-java#2658, which proposes awslc://transport (aSocketwhose streams are thedial-stdiochild process, mirroring the existingNamedPipeSocket), plus the lifecycle handlingwslcneeds for host port relays and Windows-path bind mounts.So the ordering is: docker-java gains the transport, cf docker-java/docker-java#2659 and releases a version, then Testcontainers picks it up and adds the strategy. I have the Testcontainers side working locally against a locally-built docker-java and I will raise it as a draft PR.
Benefit
WSLC support out of the box, no more need for docker or podman on Windows
Alternatives
** Keep using podman or docker
Set
DOCKER_HOST=wslc://localhostmanually. Works once docker-java understands the scheme, and is a reasonable escape hatch, but it means every developer and CI job on such a machine has to know to do it — which is exactly the discovery problem the strategies exist to solve.A
~/.testcontainers.propertiesstrategy override. Same objection, plus it has to name a class that does not exist upstream.Reach the daemon over TCP inside the VM. Requires reconfiguring
dockerdinside the WSL container VM to listen on a port and exposing it to the host — insecure, non-default, and undoes the isolation the runtime is providing.Would you like to help contributing this feature?
Yes