WSL2 + PgVector 远程连接排坑记
从 Docker 安装到跨机 PostgreSQL 连接的血泪实录
一、场景回顾
本地机器:Windows 10 + WSL2 Ubuntu 24.04
目标:WSL 内 Docker 部署 PgVector,另一台电脑(同 Tailscale 网络)用 Navicat 远程连接
二、我的 7 次尝试(以及为什么失败)
❌ 尝试 1:直接用 WSL 内 IP(172.28.xx.xx)
操作 :另一台电脑 Navicat 填 172.28.90.34:5432
结果 :连不通
原因 :WSL2 使用 NAT 网络,WSL 内部 IP 宿主机外部不可见。
结论:除非改用 WSL1(桥接网络),否则这条路走不通。
❌ 尝试 2:只配 pg_hba.conf
操作 :容器内修改 pg_hba.conf 加 host all all 0.0.0.0/0 trust
结果 :localhost 能连,远程仍不通
原因 :远程连的不是走 localhost,WSL2 NAT 挡住了。
结论:pg_hba.conf 是必要的,但不是充分条件。
✅ 尝试 3:netsh portproxy(端口转发)
操作:
powershell
netsh interface portproxy add v4tov4 listenport=5432 listenaddress=0.0.0.0 connectport=5432 connectaddress=172.28.90.34
结果 :本机 Test-NetConnection 通过,但远程连不通
原因 :端口 5432 同时被 Docker 端口映射、PortProxy 和后续的 Tailscale Serve 争抢,出现了冲突。
结论:方向对了,但端口选择有问题。
❌ 尝试 4:加 Tailscale 防火墙规则
操作:
powershell
New-NetFirewallRule -DisplayName "Allow Tailscale 5432" -Direction Inbound -InterfaceAlias "Tailscale" -Protocol TCP -LocalPort 5432 -Action Allow
结果 :仍然不通
原因 :防火墙规则已经放行了,问题不在防火墙,在端口争抢。
结论:好思路但用错了地方。
✅ 尝试 5:tailscale serve
操作:
powershell
tailscale serve --bg --tcp 5432 tcp://172.28.90.34:5432
结果 :能 serve 但远程仍连接失败
原因 :tailscale serve 默认绑定了 5432,与 netsh portproxy 冲突。
结论:tailscale serve 可以用来暴露端口,但要注意冲突。
✅ 尝试 6:换端口 15432 ✓✓✓(最终成功)
操作:
powershell
tailscale serve --tcp=5432 off
netsh interface portproxy add v4tov4 listenport=15432 listenaddress=0.0.0.0 connectport=5432 connectaddress=172.28.90.34
netsh advfirewall firewall add rule name="WSL-PG-15432" dir=in action=allow protocol=TCP localport=15432 profile=any
结果 :✅ 连接成功!
原因:15432 端口无冲突,portproxy 独占,数据流清晰:Remote → 100.124.7.8:15432 → Windows → WSL 5432 → PgVector
三、数据流图解
另一台电脑 (Tailscale)
│
│ Navicat → 100.124.7.8:15432
│
▼
Windows 宿主机
│ netstat portproxy
│ 15432 → 172.28.90.34:5432
│
▼
WSL2 Ubuntu
│ Docker 端口映射
│ 5432 → 容器 5432
│
▼
PgVector 容器 (pgvector/pgvector:pg14)
│ pg_hba.conf: trust
│ listen_addresses = '*'
│
▼
PostgreSQL 数据库
四、下次遇到怎么快速排查(速查表)
4.1 问题在哪层?
| 症状 | 问题可能在哪 |
|---|---|
| 远程 ping 不通 IP | 网络层:Tailscale 未连接 / 网段不同 |
| ping 通但 Navicat 报连接失败 | 转发层:端口转发没配或冲突 |
| TCP 能连上但马上断开 | 认证层:pg_hba.conf 配置不对 |
| 连接后报密码错 | 认证层:认证方式不匹配(scram vs md5 vs trust) |
4.2 快速定位命令
bash
# 1️⃣ 查 WSL 最新 IP(WSL 每次重启 IP 都会变!)
hostname -I
# 输出:172.28.90.34 172.17.0.1
powershell
# 2️⃣ 查端口转发列表
netsh interface portproxy show all
powershell
# 3️⃣ 查端口是否被占用(如果返回 LISTENING 说明被占了)
netstat -ano | findstr :5432
powershell
# 4️⃣ 查 Tailscale 转发冲突
tailscale serve status
bash
# 5️⃣ 查容器内 PostgreSQL 是否在监听
docker exec spring-ai-postgres cat /var/lib/postgresql/data/postgresql.conf | grep listen_addresses
bash
# 6️⃣ 查容器内认证配置
docker exec spring-ai-postgres cat /var/lib/postgresql/data/pg_hba.conf | grep -v "^#" | grep -v "^$"
4.3 标准修复流程(5 分钟搞定)
⚠️ WSL 每次重启 IP 会变,以下操作需要每次重新执行。
第一步:查 WSL 最新 IP
bash
hostname -I
# 记下第一个 IP,如 172.28.90.34
第二步:清理旧规则 + 添加新转发(用不同端口)
powershell
# 删旧规则
netsh interface portproxy reset
# 加新规则,用 15432 避免冲突
netsh interface portproxy add v4tov4 listenport=15432 listenaddress=0.0.0.0 connectport=5432 connectaddress=172.28.90.34
# 防火墙放行
netsh advfirewall firewall add rule name="WSL-PG-15432" dir=in action=allow protocol=TCP localport=15432 profile=any
第三步:验证
powershell
Test-NetConnection -ComputerName 100.124.7.8 -Port 15432
# 应显示 TcpTestSucceeded : True
第四步:另一台电脑连
主机: 100.124.7.8 (Tailscale IP)
端口: 15432
用户: postgres
密码: 123456
五、核心教训
- WSL2 的 NAT 是罪魁祸首------所有外部访问都要走 Windows 端口转发
- 端口冲突是隐藏杀手------Docker 端口映射 + PortProxy + Tailscale Serve 抢同一个端口时,一定要用新端口隔离
- WSL 重启 IP 会变 ------
hostname -I查最新 IP 是第一步 - 从错误信息定位层级------"server closed connection" 是 TCP 通但认证拒绝,"timeout" 是网络层根本不通
- 远程连接不能直接用 WSL 内部 IP 172.28.xx.xx------必须通过宿主机 IP 或 Tailscale IP