Docker Desktop 不支持 IPv6 端口映射,因其宿主机代理层(如 WSL2/vpnkit)仅绑定 IPv4 的 0.0.0.0,不解析 [-p [::1]:8080:80] 中的 IPv6 地址,导致命令静默降级为 IPv4 映射且 ss -tln 仅显示 *:8080;根本原因是其 daemon 未启用 IPv6 host network support,且内置端口转发模块不处理 IPv6 主机地址。

不能直接设置 IPv6 端口映射 —— Docker Desktop(尤其是 Windows/macOS 上基于 WSL2 或 HyperKit 的版本)默认不监听 IPv6 地址,docker run -p [::1]:8080:80 会失败或静默降级到 IPv4,这不是配置遗漏,而是底层网络栈限制。
为什么 docker run -p [::1]:8080:80 不生效
Docker Desktop 的宿主机代理层(如 WSL2 的 dockerd 或 macOS 的 vpnkit)只绑定 IPv4 的 0.0.0.0。即使容器内服务监听 [::]:80,Docker 也不会把 IPv6 地址暴露给宿主机网络栈。执行该命令后,docker ps 显示的映射仍是 0.0.0.0:8080->80/tcp,且 curl http://[::1]:8080 会连接拒绝。
- 根本原因:Docker Desktop 的 daemon 没有启用 IPv6 host network support,且其内置的端口转发模块不解析 IPv6 主机地址
- 验证方式:
ss -tln | grep :8080只能看到*:8080(IPv4 any),看不到[::]:8080 - 例外情况:Linux 原生 Docker(非 Desktop)可启用
"ipv6": true并配置fixed-cidr-v6,但 Desktop 不暴露该配置入口
替代方案:用 iptables(WSL2)或 pfctl(macOS)手动转发 IPv6 流量
在 WSL2 中,你可以绕过 Docker Desktop 的限制,直接在 WSL2 发行版里用 iptables 把宿主机 IPv6 地址上的流量 DNAT 到容器 IPv4 地址(注意:不是容器 IPv6 地址,因为 WSL2 默认不给容器分配全局 IPv6)。
- 先获取容器 IPv4 地址:
docker inspect -f '{{.NetworkSettings.IPAddress}}' <container-name></container-name>(例如172.17.0.2) - 确认 WSL2 已启用 IPv6 转发:
sysctl net.ipv6.conf.all.forwarding应为 1;若否,临时开启:sudo sysctl -w net.ipv6.conf.all.forwarding=1 - 添加规则(将宿主机
[2001:db8::1]:8080转发到容器172.17.0.2:80):sudo ip6tables -t nat -A PREROUTING -p tcp --dport 8080 -d 2001:db8::1 -j DNAT --to-destination 172.17.0.2:80 - 确保 WSL2 防火墙放行该端口:
sudo ip6tables -A INPUT -p tcp --dport 8080 -j ACCEPT - ⚠️ 注意:该规则重启 WSL2 后失效,需写入
/etc/wsl.conf或启动脚本持久化
更可靠的做法:改用原生 Linux + Docker 引擎
如果你真需要稳定、可配置的 IPv6 端口映射(比如做公网 IPv6 服务穿透),Docker Desktop 是错误工具链。应切换到:
- 物理机或云服务器上安装原生
docker-ce(非 Desktop) - 编辑
/etc/docker/daemon.json,显式启用 IPv6:{ "ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64" } - 重启服务:
sudo systemctl restart docker - 此时
docker run -p [::]:8080:80 nginx才真正监听[::]:8080,ss -tln6 | grep :8080可见结果
真正的难点不在“怎么填端口”,而在于 Docker Desktop 本质是单向桥接器:它把 IPv4 流量从宿主机带到容器,但不参与 IPv6 地址分发与路由。想走通 IPv6,就得跳出 Desktop 的 GUI 和封装逻辑,直连引擎层或换环境。


















