
最近我尝试在 Windows 10 上使用 Docker Desktop 和 WSL2 来自建 Coolify 自托管平台,整体部署流程看似顺利,但我却遇到了一个典型的网络问题 —— 容器内的服务正常运行,端口映射也显示无误,但在 Windows 本机上却始终无法访问 http://localhost:8080。这篇文章就是我完整的排查过程与解决方案分享,供遇到类似问题的朋友参考。
一、环境准备与部署 Coolify
我的基础环境如下:
- Windows 10 (19045)
- Docker Desktop 4.30.0
- WSL2 + Ubuntu 22.04
- 使用 docker-compose 启动 Coolify 容器
Coolify 的部署命令相当简单:
git clone https://github.com/coollabsio/coolify.git
cd coolify
docker compose up -d
Docker 显示容器正常运行,端口映射也正确:
docker ps
CONTAINER ID IMAGE PORTS NAMES
abc123456789 coollabsio/coolify 0.0.0.0:8080->8080/tcp coolify
在容器内部执行以下命令也能看到 Nginx 正常监听:
netstat -tulnp | grep 8080
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1/nginx: master
用容器内的 curl 测试也能返回响应:
curl http://localhost:8080
# 正常返回 HTML
二、问题表现:宿主机访问失败
但当我从 Windows 端尝试访问:
http://localhost:8080
或者 PowerShell 执行:
curl http://localhost:8080
却始终返回:
curl: (7) Failed to connect to localhost port 8080: Connection refused
浏览器则显示 ERR_EMPTY_RESPONSE 或 ERR_CONNECTION_REFUSED。
我随后尝试用以下方式访问:
- localhost:8080
- 127.0.0.1:8080
- 172.19.x.x:8080(Docker bridge IP)
- wsl hostname:8080
都失败。
三、常规排查路径
1. 检查容器绑定是否正确
docker inspect coolify | grep -i port
# 显示 "0.0.0.0:8080->8080/tcp",没问题
2. Windows 防火墙/杀软干扰?
我一度怀疑是 Kaspersky 或 Defender 拦截,但关闭 Kaspersky 后仍无法访问。
随后我用 PowerShell 手动开放端口:
netsh advfirewall firewall add rule name="Coolify8080" dir=in action=allow protocol=TCP localport=8080
没有效果。
3. 使用 netsh portproxy 尝试转发
我尝试通过 netsh interface portproxy 建立端口转发:
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=127.0.0.1 connectport=8080 connectaddress=172.20.0.2
其中 172.20.0.2 是 docker inspect 查到的容器 IP。
结果依然无效。
四、根因:WSL2 网络隔离
深入调查后我发现:在 WSL2 中运行的 Docker 容器,与 Windows 本机并不共享网络栈,虽然 docker ps 显示端口映射,但这其实是暴露在 WSL2 虚拟网卡上的,Windows 并不能直接访问这些端口。
默认 Docker Desktop 在 WSL2 模式下启动时,不会自动做 WSL 和 Windows 的端口桥接。
五、解决方案
✅ 方法一:开启 Docker Desktop 的端口桥接(推荐)
确保 Docker Desktop 设置中 启用了 WSL2 集成与端口转发:
- 打开 Docker Desktop
- 进入 Settings → General
- 勾选 Use the WSL 2 based engine
- 勾选 Expose daemon on tcp://localhost:2375 without TLS
- 勾选 Use Docker Compose V2
- 重启 Docker Desktop
然后重新运行容器。
此时你应该可以直接通过浏览器访问:
http://localhost:8080
✅ 方法二:将容器运行在 host 网络模式下(仅适合 Linux)
如果你用的是纯 Ubuntu(非 Windows 下的 WSL),你可以用 –network host 模式启动容器。但在 Docker Desktop 的 WSL2 环境中 host 模式不可用,不要尝试。
✅ 方法三:通过 WSL 的 IP 转发
在 PowerShell 中获取 WSL 子系统 IP:
wsl hostname -I
# 假设返回 172.28.112.1
然后手动添加代理:
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=8080 connectaddress=172.28.112.1 connectport=8080
这个方案需要保证防火墙未屏蔽该流量,并在每次 WSL 重启后重新设置 IP。
六、经验技巧
在 WSL2 和 Docker Desktop 混合架构下,自托管服务部署最容易踩的坑就是网络转发。尽管容器内服务正常,但没有合适的桥接机制,Windows 是无法直接访问这些端口的。
推荐做法是始终使用 Docker Desktop 自带的 WSL 端口映射机制,不要手动配置 portproxy,除非你非常确定 WSL IP 是固定的。
如果你也在 Windows + WSL2 上部署服务,不妨优先确认 Docker Desktop 的配置是否正确。否则,看似“容器端口已暴露”的假象,会让你陷入不必要的排查困境。











