Problem connecting to WSL docker host

My VS Code Torizon debug system was previously working OK, but I’m now having problems pulling the docker image down to the Torizon target system.

Here’s my setup;
Windows host running Docker Desktop (4.34.1)
WSL (Ubuntu 22.04)
VS Code - latest (3.1.1)

I’ve got a small local network:
Windows Host: 192.168.8.227
Torizon target: 192.168.8.226

I can ping each device from the other. On the Windows host, “curl http://localhost:5002/v2/” gives me a good HTML response.

From the Torizon target, I’m able to “telnet 192.168.8.227:5002” without any problem, so I know that port 5002 is able to get through the Windows firewall.

On the Torizon target, “curl http://192.168.8.227:5002/v2/” gives me “Recv failure: Connection reset by peer”, so I’m unable to pull the image down to the target.

The Torizon target’s daemon.json file has “insecure-registries” : [“192.168.8.227:5002”], so that should be OK.

The issue seems to be that the docker daemon in the container running on Windows is not being exposed to the clients of the Windows device, even though the firewall is open.

Is there something I’m missing with the docker/container config?

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello! Thank you for your detailed description of the setup and the troubleshooting steps you’ve taken so far.

Given your observations, it looks like the network connection between your Torizon target and the Windows host running Docker Desktop is established (as shown by successful telnet), but Docker’s local registry is not responding as expected when you attempt to pull images.

Here are the key things to check and steps you might be missing in your Docker/VS Code Torizon workflow:

1. Docker Desktop Registry Network Exposure

Docker Desktop on Windows (especially when using WSL2) runs containers and registries inside a special network space that isn’t always automatically exposed to your local network. By default, the registry may only be accessible via localhost on Windows, not from other hosts (like your Torizon target).

2. Utilizing the share-wsl-ports.xsh Script

The Torizon VS Code extension includes automation to expose WSL ports to the host using the share-wsl-ports.xsh script. This script opens the necessary firewall rules and relays traffic from your Windows IP to the internal WSL network. It should be triggered automatically when the extension activates in a WSL2 environment, but sometimes it may fail, especially if there was a system/environmental change.

Please reference:

Steps to Try

A. Manually ensure Port Exposure

  1. Restart the VS Code Torizon Extension inside WSL2.

    • Sometimes reloading or restarting VS Code with the Torizon workspace in your WSL2 shell will rerun the port sharing script and set up port forwarding properly.
  2. Check the status of the share-wsl-ports script:

    • Locate the script (typically inside your workspace at .vscode/share-wsl-ports.xsh) and run it manually in your WSL2 terminal:
      .vscode/share-wsl-ports.xsh
      
    • Watch for errors or warning messages.
  3. Check that the Docker registry is listening on the right interfaces:

    • From Windows, run:
      netstat -an | find "5002"
      
    • The output should show 0.0.0.0:5002 or your Windows LAN IP, not just 127.0.0.1:5002.

B. Review Windows Firewall and NAT Rules

  • Make sure the Windows firewall hasn’t changed rules that block forwarding to WSL.
  • Check for any third-party firewalls or proxies that could block the connection.

C. Restart Key Components

  • Restart Docker Desktop.
  • Restart VS Code with your Torizon workspace.
  • Restart your WSL2 Ubuntu instance:
    wsl --shutdown
    
    Then, reopen your terminal.

D. Try Accessing Registry Within WSL

  • From WSL2 Ubuntu shell, check if the registry is reachable:
    curl http://localhost:5002/v2/
    
    This should work and help confirm the registry server is up and the issue is with Windows-to-WSL bridging.

If all the above checks are OK, but you still see “Connection reset by peer” from the Torizon target, it’s almost always an issue with the Windows/WSL2 port relay—not with Docker or the daemon.json on the target.

For deeper info, you may also visit:

Let me know if these steps help, or if you need more detailed diagnostics!

Best regards,
Toradex AI Assistant.

Can you give me some more specific information about the location of the share-wsl-ports.xsh script? Is it on the Windows host, WSL, the target? What’s the path?

After running share-wsl-ports, and running netsgrtat -an, I can see that my docker registry is not listening on 127.0.0.1:5002 - only 0.0.0.0:5002.

TCP 0.0.0.0:5002 0.0.0.0:0 LISTENING
TCP 0.0.0.0:5002 0.0.0.0:0 LISTENING
TCP [::]:5002 [::]:0 LISTENING
TCP [::1]:5002 [::]:0 LISTENING
UDP 0.0.0.0:5002 :

@jonmills

Please first check the local WSL firewall rules, some systems are applying more strict rules:

sudo iptables -L -v -n

Please share the output with us, run in a new WSL terminal.

Thanks @matheus.tx .

Here’s the output;

sudo iptables -L -v -n
[sudo] password for jonmills:
Chain INPUT (policy ACCEPT 219 packets, 276K bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER-USER all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-FORWARD all – * * 0.0.0.0/0 0.0.0.0/0

Chain OUTPUT (policy ACCEPT 186 packets, 56688 bytes)
pkts bytes target prot opt in out source destination

Chain DOCKER (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp – !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:5000
0 0 DROP all – !docker0 docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-BRIDGE (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER all – * docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-CT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all – * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED

Chain DOCKER-FORWARD (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-CT all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-ISOLATION-STAGE-1 all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-BRIDGE all – * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all – docker0 * 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-ISOLATION-STAGE-2 all – docker0 !docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all – * docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all – * * 0.0.0.0/0 0.0.0.0/0

Please try to run the following in a WSL terminal:

sudo iptables -I FORWARD -i docker0 -j ACCEPT && sudo iptables -I FORWARD -o docker0 -j ACCEPT

After that, please share with us again the output of the sudo iptables -L -v -n.
Also, try to deploy the debug sessions again to see if something changes.

BR,

Thanks Matheus.

Here’s the updated output. Unfortunately it didn’t fix the problem.

Also, on my Windows host, the following command is still successful:
curl http://localhost:5002/v2/

and the following command still fails:
curl http://127.0.0.1:5002/v2/

so it seems to be a problem mapping the ports into the docker registry in WSL.

sudo iptables -L -v -n
Chain INPUT (policy ACCEPT 1 packets, 76 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all – * docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all – docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-USER all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-FORWARD all – * * 0.0.0.0/0 0.0.0.0/0

Chain OUTPUT (policy ACCEPT 1 packets, 76 bytes)
pkts bytes target prot opt in out source destination

Chain DOCKER (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp – !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:5000
0 0 DROP all – !docker0 docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-BRIDGE (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER all – * docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-CT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all – * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED

Chain DOCKER-FORWARD (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-CT all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-ISOLATION-STAGE-1 all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-BRIDGE all – * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all – docker0 * 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-ISOLATION-STAGE-2 all – docker0 !docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all – * docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all – * * 0.0.0.0/0 0.0.0.0/0

@jonmills thanks, now please run:

sudo iptables -I DOCKER 1 -i !docker0 -o docker0 -j ACCEPT

Again, please share the output of the sudo iptables -L -v -n after the command and try to deploy the debug session.

BR,

I assume that the ! before the first docker0 was a typo?

sudo iptables -I DOCKER 1 -i docker0 -o docker0 -j ACCEPT

sudo iptables -L -v -n
Chain INPUT (policy ACCEPT 1 packets, 80 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all – * docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all – docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-USER all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-FORWARD all – * * 0.0.0.0/0 0.0.0.0/0

Chain OUTPUT (policy ACCEPT 4 packets, 208 bytes)
pkts bytes target prot opt in out source destination

Chain DOCKER (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all – docker0 docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp – !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:5000
0 0 DROP all – !docker0 docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-BRIDGE (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER all – * docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-CT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all – * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED

Chain DOCKER-FORWARD (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-CT all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-ISOLATION-STAGE-1 all – * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-BRIDGE all – * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all – docker0 * 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-ISOLATION-STAGE-2 all – docker0 !docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all – * docker0 0.0.0.0/0 0.0.0.0/0

Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all – * * 0.0.0.0/0 0.0.0.0/0

@matheus.tx what’s the preferred development environment (what are most devs using)? This Windows/WSL combination always seems to cause some pain. Would I be better moving to a Linux environment, or is it possible to debug via an external Docker registry (which doesn’t use WSL)?

So, I’m assuming that the second command also did not solve the issue, am I right? Although your iptables output seems correct now :thinking:.

what’s the preferred development environment (what are most devs using)? This Windows/WSL combination always seems to cause some pain.

Yeah, it’s weird how some Windows WSL 2 network environments behave, it does not seem to be in a pattern, it depends on company policies, Windows version 11 home/professional, etc. If possible better use a Debian/Ubuntu latest LTS Linux, so you will not have to deal with this Windows/WSL Linux stuff.

Thanks Matheus,

Yes, unfortunately, I’m still unable to curl from the API using any other address than localhost, so I’m assuming the problem is on the Windows side, rather than anything to do with the WSL firewall.

Maybe I’ll take some time to set up a Linux dev machine. This WSL Docker registry stuff seems pretty hard to get right. I’d still like to get my Windows setup working in the short term, if you’ve got any other things I can check?

Hello @jonmills,

I know that Matheus is currently experimenting with some things so that the extension does not depend on Windows firewall anymore. He will update you soon. Thanks for your patience.

Thanks for the feedback @rudhi.tx .

I’m currently working in a Ubuntu VM (which is slow) (and considering re-building my laptop to run Linux natively), which is much easier than trying to work around the WSL firewall issues, but it would be nice to have the option of working in Windows.

Hey @jonmills

We have some experiments under the dev branch that are ready for feedback. If you feel comfortable trying, it would be great. Before all, please follow the instructions here on this page Settings - Using Templates Development Branch | Toradex Developer Center to set your VS Code settings to point to the latest development branch of templates.
Also, you will need the pre-release version of the extension. To get the latest development pre-release version, go to the marketplace, Torizon extension, and then click on Switch to Pre-Release Version:

To make sure VS Code will load the new extension version, reload the window.
A new project needs to be created from scratch to test the new Docker host feature, use the old projects previously created on old versions will not work, ok?

Let me know.

BR,

Thanks Matheus.

I believe that I’ve followed your instructions correctly. Here’s the error I see;

  • Executing task: xonsh .conf/validate-deps-running.xsh

xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE =
Traceback (most recent call last):
File “.conf/validate-deps-running.xsh”, line 20, in
from torizon_templates_utils.network import is_in_gitlab_ci_container
ImportError: cannot import name ‘is_in_gitlab_ci_container’ from ‘torizon_templates_utils.network’ (/home/jonmills/.local/pipx/venvs/xonsh/lib/python3.10/site-packages/torizon_templates_utils/network.py)

  • The terminal process “xonsh ‘.conf/validate-deps-running.xsh’” failed to launch (exit code: 1).
  • Terminal will be reused by tasks, press any key to close it.

Hey @jonmills, I’m on vacation right now, but already forwarded your report to the team. Thanks for trying it, I hope to have news soon.

BR,

Hello @jonmills !

Sorry for this issue. It should be fixed now, so please try again.
If you want to verify that you have the right versions, you can run pipx runpip xonsh list after creating your project.
You should see torizon_templates_utils with version 0.0.11.

Thanks!