Remote control of Docker Desktop on Windows with WSL2

I’m running Jenkins natively on Windows (not in a container). I installed the Docker plugin so that I can run some agents as docker containers. I already have Docker Desktop installed and working on the same machine. It is set up to run in WSL2 mode.

When setting up the configuration in Jenkins, Jenkins is looking for the Docker Host URI.

I don’t have “Expose daemon on tcp://localhost:2375” checked.
I do have use the WSL 2 based engine checked
I do have the “Add the *.docker.internal names to the hosts etc/hosts file” <-Verified this is working

No matter what I do though, I don’t see any processes listening on port 2376.
I verified that the “Docker Desktop Service” is running.

I can start new containers from both the Docker Desktop app, and the docker cli.

Any ideas? Tried values of:
tcp://127.0.0.1:2375
tcp://127.0.0.1:2376
I’ve tried pointing to the IP returned by "wsl -d docker-desktop hostname -i "
tcp://host.docker.internal:2375
tcp://host.docker.internal:2376

I’m out of ideas…

By default, the docker daemon does only expose the docker sock via Unix domain socket (+ Windows pipe on Docker Desktop for Windows), but not to a tcp port. If you need to bind it to a tcp port, you must either explicitly configure it or use something like docker-socket-proxy to bind and expose it instead.

With Docker CE on Linux, this would be configured in /etc/docker/daemon.json (which usually needs to be created first).

With Docker Desktop, it can be configured in “Settings” → “Docker Engine”. But I have no idea how to configure the pipe-based docker socket binding, that is required from the Windows docker cli tool, and probably Docker Desktop itself. Honestly, I wouldn’t touch it and use the docker-socket-proxy instead.

WARNING: by default the docker socket has no built-in authentication → everyone able to reach the port can control the Docker Engine without any restrictions.

I am afraid you will have to wait for someone who actually uses such a setup.

Does docker-socket-proxy exist on Windows?

docker-socket-proxy will only work if there is a socket that Docker daemon is already listening to. Something doesn’t see right because there is a setting “Expose daemon on tcp://localhost:2375 without TLS”, which, even when checked, doesn’t make the Docker Host available on port 2375.

I think there might be something weird going on with WSL2 interaction.

You mean the one that the docker cli and Docker Desktop use to interact with the Docker Engine? Like I wrote in my previous post, it’s a pipe and not a tcp binding.

I just tried it, and it works like a charme:

docker container run -d --privileged --name dockerproxy -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 tecnativa/docker-socket-proxy
Unable to find image 'tecnativa/docker-socket-proxy:latest' locally
latest: Pulling from tecnativa/docker-socket-proxy
df20fa9351a1: Pull complete
0ac445442245: Pull complete
f22a16c95ab7: Pull complete
52730608fc83: Pull complete
Digest: sha256:6c22b9545adc95258af9deffdde6c0ce0a0a70716771e5a4e02d24d1b6e0dda1
Status: Downloaded newer image for tecnativa/docker-socket-proxy:latest
9905497fc0d92893cecd87daf90f53b63c6e09b7889c6374f664930ebb021e67

# set DOCKER_HOST to use dockerproxy
$env:DOCKER_HOST = "tcp://127.0.0.1:2375"

# list containers using dockerproxy (which fails because I didn't allow anything)
docker docker ps
Error response from daemon: <html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>

# unset DOCKER_HOST to use default docker socket connection using npipe:////./pipe/docker_engine

$env:DOCKER_HOST = ""

# list containers using defaul Windows pipe
docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED         STATUS         PORTS
          NAMES
9905497fc0d9   tecnativa/docker-socket-proxy   "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   127.0.0.1:2375->2375/tcp   dockerproxy

Now remove the container and allow it to access the container endpoint:

docker container run -e CONTAINERS=1 -d --privileged --name dockerproxy -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 tecnativa/docker-socket-proxy

# use dockerproxy
$env:DOCKER_HOST = "tcp://127.0.0.1:2375"

docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED         STATUS         PORTS
          NAMES
d2942646f631   tecnativa/docker-socket-proxy   "/docker-entrypoint.…"   7 seconds ago   Up 5 seconds   127.0.0.1:2375->2375/tcp   dockerproxy

# try to delete it (still using dockerproxy)
docker rm dockerproxy
Error response from daemon: <html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>

# unset dockerproxy
$env:DOCKER_HOST = ""

docker rm -f dockerproxy
dockerproxy