Development and AI · Clash Technical Blog

Routing Docker and WSL2 Through Clash: Image Pull Timeouts and Network Configuration

docker pull, WSL2 downloads, and requests inside containers come from different processes. Check the host address and relevant proxy settings for the error location, pass variables separately to builds or containers, and use NO_PROXY to keep database and internal-service access direct.

  • Docker
  • WSL2
  • Development environments
On this page

A common mistake in a development environment is copying the proxy address that works on your computer into every terminal and container. Check which process reports the error and whether it can reach the host running the proxy. Save persistent settings after the connection test passes, while keeping direct access to internal services such as databases.

Proxy Settings for docker pull, WSL Downloads, and Container Requests

Which Program Sent the Failing Request?

Failed actionProgram Sending the Request
curl / apt / git times out inside WSLA process in the WSL distribution
docker pull times outDocker Desktop or Docker Engine daemon
RUN apt-get times out during buildBuildKit / build container
The application request fails after startupRunning container

Clash listening on 127.0.0.1 in Windows only guarantees access from that Windows machine. WSL2 uses a NAT virtual network by default, and containers also have independent networking. Their requests to 127.0.0.1 usually reach themselves, not the host.

Proxy paths among Windows, WSL2, and containers
  1. Clash on WindowsListen on a local-network-reachable mixed-port
  2. WSL2Access that port using the host address
  3. Docker buildExplicitly receive HTTP_PROXY and HTTPS_PROXY
  4. Tools inside the containerThen configure Git, npm, or the package manager

When Windows, WSL2, or a container connects to 127.0.0.1, it usually reaches its own network environment. Enter a host address that is reachable from the environment using the proxy.

Allow WSL to Reach the Windows Proxy Port

First inspect the actual HTTP or mixed-port in Clash. A common example is 7890, but your client may differ. When WSL accesses it through the host IP, the connection is treated as local-network traffic, so the client must allow LAN access and listen on an address reachable from WSL.

Allowing LAN access expands the port's reachability. Use it only on a trusted private home or work network and have Windows Firewall restrict sources. Do not expose an unauthenticated proxy on public Wi-Fi or the internet. Disable LAN access after testing if you no longer need it.

Host Addresses in Default NAT and Mirrored Networking

In default NAT mode, WSL can read the next hop of its default route, which is usually the Windows host's address in the WSL virtual network. With mirrored networking enabled on Windows 11 22H2 and later, WSL can access Windows services directly through 127.0.0.1.

Default WSL NAT test; 7890 is the Clash port to replace
HOST_IP=$(ip route show | grep -i default | awk '{ print $3 }')
CLASH_PORT=7890
echo "Windows host: $HOST_IP"
curl -I -x "http://${HOST_IP}:${CLASH_PORT}" https://example.com

Only after this curl receives an HTTP response should you set WSL environment variables. If the proxy port immediately returns Connection refused, the issue is Clash listening, LAN access, or the firewall. If the port is reachable but the external request shows timeout, then inspect the node and rules.

Set HTTP_PROXY and HTTPS_PROXY in the WSL shell

Temporary for the current WSL shell; 7890 is a port placeholder
HOST_IP=$(ip route show | grep -i default | awk '{ print $3 }')
CLASH_PORT=7890
export HTTP_PROXY="http://${HOST_IP}:${CLASH_PORT}"
export HTTPS_PROXY="http://${HOST_IP}:${CLASH_PORT}"
export NO_PROXY="localhost,127.0.0.1,::1"
curl -I https://example.com

Temporary variables are read by programs started from the current terminal. Repeat the same HTTPS request with git or curl, then add the working settings to your shell startup file. For HTTP URLs, curl reads lowercase http_proxy; HTTP_PROXY alone will not work.

The HTTP transport in apt reads lowercase http_proxy and no_proxy, or its own Acquire::http::Proxy setting. When starting it with sudo, also check whether the environment is retained. Do not treat the variable block above as universal proxy settings for every tool.

Supported Windows versions of WSL can also use autoProxy=true in .wslconfig to import Windows HTTP proxy information. Restart WSL after enabling it and inspect the actual variable values.

NO_PROXY should include services available only inside WSL so access to localhost does not detour through the Windows proxy. Add internal corporate domains and private ranges according to the actual network.

Proxy Entry Points for Docker Desktop and Standalone Engine

Docker Desktop image pulls and WSL shell downloads come from different processes. Running export HTTP_PROXY only in WSL does not automatically configure image pulls in Desktop.

Open Settings in Docker Desktop, enter HTTP and HTTPS proxies reachable from the host under Resources / Proxies, whose labels may vary by version, and apply the settings.

If the page separates Docker Desktop proxy and Containers proxy, check Containers proxy for image pulls. Docker Desktop proxy is only a fallback when Containers proxy is not configured. Verify the change with docker pull.

Official Docker documentation explicitly states that Desktop does not read daemon proxy settings from daemon.json. A working WSL terminal does not let you skip Docker Desktop's own proxy settings.

Only when using standalone Linux Docker Engine rather than Docker Desktop should you configure daemon proxies through daemon.json or the systemd environment according to Engine documentation, then restart the Docker service. Identify what you are running first so you do not edit a file that is never read.

Pass Proxy Settings Separately to Image Builds and Running Containers

Docker client configuration can automatically inject proxy variables into new containers and builds or pass them explicitly for a single command. Use --build-arg at build time and --env at runtime. Do not use ENV in a Dockerfile to persist a credential-bearing proxy address; image history and configuration may retain it.

Run this example from a project directory containing a Dockerfile. demo-app is the image name for this build; replace it for your project as needed. This is not a standalone connectivity test. First use the earlier curl check to test whether the proxy port is reachable.

Existing-project example for Docker Desktop; replace 7890 with your Clash port
CLASH_PROXY=http://host.docker.internal:7890

docker build \
  --build-arg HTTP_PROXY="$CLASH_PROXY" \
  --build-arg HTTPS_PROXY="$CLASH_PROXY" \
  -t demo-app .

docker run --rm \
  --env HTTP_PROXY="$CLASH_PROXY" \
  --env HTTPS_PROXY="$CLASH_PROXY" \
  --env NO_PROXY="localhost,127.0.0.1" \
  demo-app

Docker Desktop normally provides host.docker.internal for reaching the host. Availability in native Linux Engine depends on the environment and may require an explicit host gateway or extra host-gateway mapping. Before running the command, use curl or application logs inside the container to confirm that the hostname and port are reachable.

NO_PROXY: Keep Database and Internal-Service Connections Direct

Database names, Compose service names, localhost, and internal subnets normally should not use an external proxy. Add the actual internal domains to NO_PROXY so requests to db:5432 or redis:6379 do not first go to the Windows proxy. Wildcard and CIDR support differs between tools; after setting the variable, print it in the target process and make a real request.

If a proxy address contains a username or password, do not put it in a public compose.yaml, Dockerfile, or image. Use a local environment file or the project's secret-management method, and ensure logs do not print the complete URL.

Complete four validations for actual use

  • curl inside WSL receives a response through Windows Clash
  • docker pull can retrieve a small image
  • Network steps during docker build no longer time out
  • The running container can access the internet and directly reach internal services

References