The main goal of this setup is simple: run a container once, and access that exact same container from both PowerShell and WSL2, not two separate copies running in isolation. There are some genuine benefits with this setup in my opinion.
- Work across both shells naturally: I am on WSL for almost everything but occasionally I also use PowerShell for Windows side tasks. Having one engine means I never get stuck wondering “which shell did I start this container in?”
- Avoiding duplicate engine wastes resources: If WSL runs it own local rootless Podman and Windows runs Podman Desktop’s VM separately, you would have 2 entirely separate container runtime wasting CPU/RAM with no containers visible to each other.
- One source of truth for debugging: If a container from WSL is having issues, you can just check podman logs or podman inspect from PowerShell (or vice versa) without switching contexts.
- Consistent networking port access: Since its the same container, ports you map are reachable from localhost in your Windows browser and from WSL’s network stack.
Podman Desktop makes this possible because it runs a single Linux VM (podman-machine-default) that acts as your container engine. Both PowerShell and WSL2 can talk to that same machine over SSH, so a container you start in one place is immediately visible, manageable, and reachable from the other. Start a container from WSL, inspect it from PowerShell, curl it from WSL again, all pointing at the same running process.
This guide covers the setup end to end, including the gotchas that most commonly break it.
The Connection Model
Podman Desktop exposes its VM over SSH, and any CLI (Windows or WSL) is just a client dialing in. You can see this directly:
$ podman system connection list
Name URI Default
podman-machine-default ssh://user@127.0.0.1:52464/run/user/1000/podman/podman.sock false
podman-machine-default-root ssh://root@127.0.0.1:52464/run/podman/podman.sock true
Two connections always exist for one machine:
-
Rootless (
user@...): containers run under an unprivileged user inside the VM via Linux user namespaces -
Rootful (
root@...): containers run as root inside the VM
Pick one and keep both sides pointed at it consistently. That consistency is what makes “same container, both sides” actually work.
Rootless is the sensible default for local development: file ownership on bind mounts maps more predictably back to your actual user, and containers are better isolated. You only need rootful for binding to privileged ports (below 1024) or specific low-level system capabilities, which is rare for everyday work.
Gotcha #1: The Machine Itself Needs to Be Rootless, Not Just the Connection
Setting the rootless connection as default via CLI…
$ podman system connection default podman-machine-default
…can look like it worked, but Podman Desktop may keep popping up this dialog:
Rootful Podman Machine ‘podman-machine-default’ does not match default connection. This will cause podman CLI errors while trying to connect to ‘podman-machine-default’. Do you want to update the default connection?
Clicking “Yes” here silently flips your CLI default back to rootful, undoing your change. That’s because the dialog is really telling you the machine booted in rootful mode, and setting the connection default alone doesn’t match that. Fighting it at the connection level is a losing battle; it will keep reverting.
The real fix is at the machine level:
podman machine stop
podman machine set --rootful=false podman-machine-default
podman machine start
Confirm it worked by checking Podman Desktop’s UI. It should explicitly show:
Once the machine itself is rootless, the mismatch dialog stops appearing for good, and podman system connection list stays stable with rootless as default.
Note: stopping the machine kills any running containers. You will need to restart or recreate them afterward.
Gotcha #2: WSL’s Podman CLI Doesn’t Know About the Windows Machine by Default
Installing podman inside WSL via apt gives you a separate, local installation. It has no idea the Windows-side machine exists. To make it a client of that same machine:
- Install the podman CLI in WSL:
sudo apt update
sudo apt install -y podman
-
Add a connection pointing at the Windows machine, using the exact URI and port from PowerShell’s podman system connection list, with the identity path converted to WSL's
/mnt/c/...mount form:
podman system connection add podman-machine-default \
--identity "/mnt/c/Users/<your-username>/.local/share/containers/podman/machine/machine" \
ssh://user@127.0.0.1:<port>/run/user/1000/podman/podman.sock
podman system connection default podman-machine-default
- Force WSL’s podman into remote-client mode permanently. Without this, even with a connection added and set default, WSL’s local podman binary tries to run containers locally first, which is what throws:
Error: command required for rootless mode with multiple IDs: exec: "newuidmap": executable file not found in $PATH
Fix it by setting remote mode in config:
mkdir -p ~/.config/containers
cat >> ~/.config/containers/containers.conf << 'EOF'
[engine]
remote = true
EOF
- Verify
podman ps -a
podman run --rm quay.io/podman/hello:latest
Gotcha #3: The SSH Port Changes on Every Machine Restart
The port Podman Desktop assigns (52464, 59044, and so on) is dynamic and changes on every machine restart: reboot, manual podman machine stop/start, Windows update, and so on. When that happens, WSL's connection (which has the old port hardcoded) silently breaks:
Error: unable to connect to Podman socket: failed to connect: dial tcp 127.0.0.1:52464: connect: connection refused
Fix: re-sync WSL’s connection with the current port whenever the machine restarts:
podman system connection remove podman-machine-default
podman system connection add podman-machine-default \
--identity "/mnt/c/Users/<your-username>/.local/share/containers/podman/machine/machine" \
ssh://user@127.0.0.1:<current-port-from-powershell>/run/user/1000/podman/podman.sock
podman system connection default podman-machine-default
Get the current port from PowerShell first:
podman system connection list
Verifying It Works End-to-End
Once both sides point at the same rootless machine, confirm it properly:
- Start a persistent container from either side:
podman run -d --name test-nginx -p 8080:80 docker.io/library/nginx:latest
- Check it shows up identically from both CLIs:
podman ps
podman ps
Both should list the exact same container ID.
Confirm browser access via WSL2’s automatic localhost forwarding: Open http://localhost:8080 in your Windows browser. You should see the nginx welcome page. This works regardless of which side started the container, since WSL2 forwards ports to the Windows host automatically.
Or check from the command line:
curl http://localhost:8080
Conclusion
In short: containers.conf with remote = true isn't optional here — without it, WSL's local podman binary will always try to spin up its own local engine first, regardless of what connection you've set as default. It's the one setting that actually forces WSL into "client of the Windows machine" mode rather than "separate engine that happens to have a saved connection."




Top comments (0)