Scenario combo Β· 2 tools Β· recorded 2026-08-29

Combo: Docker & WSL Environment Setup and Troubleshooting Partial

Docker and WSL installed but β€œwon't work” β€” daemon unreachable, port conflicts, exec TTY errors, containers can't reach the host, garbled WSL output, disk full, node not found in WSL; each tutorial covers one pit.

Scenario

All 7 problems in the problem-side container-wsl topic group had no combo attached (coverage-matrix gap 7/7, analyzed 2026-08-29): daemon unreachable, port conflicts, exec TTY, container-to-host access, WSL garbled output, WSL disk full, node not found in WSL. The common user scenario is "the WSL + Docker environment is installed but won't work" β€” this combo arranges them in troubleshooting order: first make the WSL base usable (encoding/disk/runtime), then make the Docker daemon reachable, and finally the container operation layer (network/port/exec). Complementary to combo-mirror-setup (mirror config): that one solves "can't pull", this one solves "can't use".

Combo members

WSL (Windows Subsystem for Linux): base environment configuration target

  • Download: official Windows (Microsoft Store / wsl --install); not a plugin, a system component
  • Version: WSL >= 2.4.4 (wsl --manage <distro> --set-sparse true needs 2.4.4+, WSL 2 is a runtime prerequisite)
  • Install:
# Encoding (problem: wsl-pipe-encoding) β€” modern WSL uses UTF-8 pipes by default, Chinese passes through fine;
# on old versions / Windows PowerShell 5.1 with per-char null bytes/garbled output, switch to Windows Terminal + UTF-8 locale inside WSL:
sudo locale-gen zh_CN.UTF-8 && sudo update-locale LANG=zh_CN.UTF-8
# Disk (problem: wsl-no-space-left) β€” vhdx sparse mode, deleted files return space automatically (WSL 2.4.4+):
#   Windows side (PowerShell): wsl --shutdown
#   wsl --manage <distro> --set-sparse true
# Runtime (problem: claude-code-router-2) β€” install Node on the WSL side, don't depend on the Windows-side npm:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs

Docker Engine: container runtime configuration target

  • Download: Docker Desktop (Windows/WSL integration) or Docker Engine (Linux official script https://get.docker.com); not a plugin
  • Version: >= 20.10 (registry-mirrors / host-gateway long-supported; measured 29.1.3 on this machine)
  • Install:
# daemon (problem: docker-daemon-connect) β€” "Cannot connect to the Docker daemon" three fixes:
#   1) Docker Desktop is running and WSL integration is enabled (Settings β†’ Resources β†’ WSL integration)
#   2) check the socket: ls -l /mnt/wsl/docker-desktop/shared-sockets/guest-services/docker.proxy.sock
#   3) or run the Engine directly: sudo systemctl enable --now docker
# Port conflict (problem: docker-port-already-allocated) β€” find the occupant and change the port:
ss -ltnp | grep <port>
docker run -p <new-port>:80 ...
# Port hijack by a leftover legacy dockerd (verified 2026-08-30) β€” container-internal curl OK, but localhost:<port> from outside returns 403/refused even after restarting Docker Desktop:
#   root cause: a stale dockerd inside WSL (29.1.3, /usr/bin/dockerd, leftover from a Docker Desktop upgrade) keeps its docker-proxy bound to the port, forwarding into the dead netns of a removed container
systemctl status docker             # legacy daemon auto-starting?
systemctl stop docker docker.socket # stop + disable the legacy daemon (after confirming nothing in-use runs under it)
systemctl disable docker docker.socket
# exec TTY (problem: docker-exec-tty) β€” interactive terminals use -it, pure scripts use -i (or drop -t):
docker exec -it <container> bash      # interactive
docker exec -i <container> command    # script/pipe
# Container-to-host access (problem: docker-host-access) β€” use host-gateway on Docker 20.10+:
docker run --add-host=host.docker.internal:host-gateway ...

Install order

  1. WSL base first: encoding (garbled output) and disk (vhdx sparse) are environment-layer, confirm them first; install Node on the WSL side first (npm from the Windows side is the root cause of ccr and other tools not finding node in WSL).
  2. Docker daemon reachable: socket exists + docker info shows the Server section, then enter the container operation layer.
  3. Container operation layer: port conflict β†’ exec TTY β†’ container-to-host access, resolve one by one in error order.

Dependency warnings

  • Conflicts: WSL (distro config/Windows side) and Docker (daemon/socket) config surfaces are independent, no shared write surface β†’ compatible; with combo-mirror-setup (daemon.json mirror) they share the single file daemon.json β€” configure the source first then troubleshoot, or merge edits, don't overwrite each other (possible-compatible, constructive judgment).
  • Versions: WSL >= 2.4.4 (--set-sparse); Docker >= 20.10 (host-gateway / registry-mirrors); Node >= 18 (WSL side, ccr runtime prerequisite).
  • Environment: wsl --shutdown restarts all WSL distros (affects running processes); --set-sparse true is incompatible with old WSL; daemon fixes may require restarting Docker Desktop (affects running containers); privileges: systemctl needs sudo.
  • China network: mirror config see combo-mirror-setup (docker-hub-pull-fail is attached to that combo); the Node install script goes through official nodesource, if slow use the npmmirror binary mirror or replace the apt source.

Acceptance check (one shot)

Run this block after configuring; all green = combo ready; any failure -> back to the matching step in the install walkthrough.
node --version
docker info 2>&1 | grep -A2 '^Server:'
ss -ltnp | grep docker-proxy || echo 'no leftover docker-proxy hijack'
docker ps

ι’„ζœŸθΎ“ε‡Ί: node >= 18; docker info shows Server section; no leftover legacy dockerd docker-proxy (if present, follow the hijack fix in Step 2); docker ps OK. Environment -> daemon -> container layers all green = ready

Note: member-level measured (WSL Node v22.22.1, daemon socket missing reproduced, port hijack reproduced+fixed 2026-08-30); container-layer commands need a working daemon.

Verification evidence

Every combo is measured in an isolated environment (smoke + write-surface check); unmeasured items are honestly marked in the text, and measurement dates are listed in the verification section below.

Verified 2026-08-29 Β· TTL expires β€” (180 days)

Measured 2026-08-29 (WSL Ubuntu + Docker 29.1.3):

  • docker-daemon-connect: reproduced for real in this environment β€” docker info Server section reported failed to connect to the docker API at unix:///mnt/wsl/docker-desktop/shared-sockets/guest-services/docker.proxy.sock: connect: no such file or directory (Docker Desktop WSL integration socket missing). Fix not measured (needs starting Docker Desktop / enabling WSL integration, a user-environment operation, red line not touched).
  • wsl-pipe-encoding: measured normal in this environment β€” PowerShell-side wsl echo "δΈ­ζ–‡ζ΅‹θ―•πŸ€„" output passed through without garbling (modern WSL defaults to UTF-8 pipes); the garbled scenario is old WSL / Windows PowerShell 5.1, the fix is given but not measured.
  • wsl-no-space-left: not reproduced in this environment (df -h / shows 766G available); --set-sparse not measured (needs wsl --shutdown, red line forbidden).
  • claude-code-router-2: /usr/bin/node v22.22.1 measured present on the WSL side in this environment β€” the root cause of "node: not found in WSL" (npm installed from the Windows side) does not hold here, disproving it the other way: installing Node on the WSL side makes the problem disappear.
  • docker port hijack by legacy dockerd (verified 2026-08-30): a stale dockerd (29.1.3, /usr/bin/dockerd) in WSL kept its docker-proxy bound to port 3000, forwarding into the dead network namespace of a removed container β€” container-internal curl OK, external localhost:3000 returned 403/refused; after systemctl stop/disable docker docker.socket the port reached the Docker Desktop engine's container directly (200 from both Windows and WSL sides). local repro log 2026-08-30 section 0.
  • docker-exec-tty / docker-port-already-allocated / docker-host-access: not measured (need a working daemon to run real containers; daemon currently unreachable).

Related problems

← All combos | Tool Catalog | Hit a problem? Submit a helpdesk card