“在本地跑得好好的OpenClaw,一放到Docker容器里,代理就不生效了……”
“明明docker-compose.yml里配了环境变量,容器里curl也能通,但OpenClaw就是不走代理……”
“更离谱的是,容器能ping通外网,但OpenClaw一跑采集任务就报网络错误……”
如果你正在经历这些,别怀疑人生——这不是你的问题,是Docker网络和OpenClaw代理解析逻辑的“双重夹击”。我在这上面折腾了好几天,踩了不下5个坑,今天一次性帮你排完。
一、问题现象:容器内代理“失灵”的典型表现
| 现象 | 可能原因 |
| 宿主机curl能通代理,容器内curl也能通,但OpenClaw报错 | OpenClaw代理解析与Docker网络叠加问题 |
| 容器能ping通外网,但OpenClaw采集失败 | 代理环境变量未正确传递到OpenClaw进程 |
| Docker Desktop刚升级后代理突然失效 | 新版Docker的容器网络隔离策略变更 |
| 配置了HTTP_PROXY但OpenClaw仍走直连 | YAML配置与容器环境变量冲突 |
二、踩坑一:环境变量没传到容器里(最常见)
很多人在docker run命令里只写这样:docker run -d --name openclaw openclaw/openclaw:latest,然后在容器里手动export HTTP_PROXY——容器重启就没了。
正确做法:在docker run时直接传环境变量,或在docker-compose.yml中配置。
方案A:docker run时直接传
docker run -d \
-e HTTP_PROXY="http://隧道ID:密码@tps.zdaye.com:8080" \
-e HTTPS_PROXY="http://隧道ID:密码@tps.zdaye.com:8080" \
-e NO_PROXY="localhost,127.0.0.1" \
--name openclaw \
openclaw/openclaw:latest
方案B:docker-compose.yml配置(推荐)
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
ports:
- "18789:18789"
environment:
- HTTP_PROXY=http://隧道ID:密码@tps.zdaye.com:8080
- HTTPS_PROXY=http://隧道ID:密码@tps.zdaye.com:8080
- NO_PROXY=localhost,127.0.0.1
volumes:
- openclaw_data:/root/.openclaw
restart: unless-stopped
验证环境变量是否生效:docker exec openclaw env | grep -i proxy
三、踩坑二:YAML配置和容器环境变量“打架”
问题根源:当你在容器里同时做了两件事——在config.yaml里配置了proxy字段,又通过-e传入了HTTP_PROXY环境变量——OpenClaw的代理加载逻辑可能产生冲突,导致两个都不生效。
解决方案:二选一,别混用。
推荐方案:只用环境变量,注释掉YAML中的proxy配置
# config.yaml - 代理配置注释掉,让环境变量接管
# proxy:
# http: "http://..."
# https: "http://..."
我的建议:在Docker环境中,优先使用环境变量方案。这是最底层、最可靠的代理配置方式,能绕开OpenClaw自己实现的代理解析逻辑。
四、踩坑三:Docker Desktop的容器网络隔离
Docker Desktop 4.29.0及以上版本引入了“隔离容器”功能,可以对容器网络流量施加自定义代理规则。如果配置不当,可能会意外拦截容器的代理流量。
检查方法:查看admin-settings.json中是否有containersProxy配置:
{
"containersProxy": {
"mode": "manual",
"http": "http://proxy.company.com:8080",
"https": "http://proxy.company.com:8080",
"transparentPorts": "*"
}
}
如果这里有配置,Docker会强制容器的网络流量走这个代理,覆盖你在容器内设置的环境变量。
解决方案:
- 方案A:如果不需要这个功能,删除或注释掉
containersProxy配置 - 方案B:如果需要保留,确保这里的代理地址配置正确,且与OpenClaw的代理设置不冲突
PAC文件配置示例(允许访问站大爷代理):
function FindProxyForURL(url, host) {
if (dnsDomainIs(host, "tps.zdaye.com")) {
return "DIRECT";
}
return "PROXY corporate-proxy:8080";
}
五、踩坑四:容器网络模式选错了
常见错误:用--network host导致代理配置失效
有些用户为了让容器和宿主机共享网络,会这样写:docker run --network host ...。这会导致容器使用宿主机的网络栈,代理行为变得不可预测。
正确做法:使用默认bridge网络 + 环境变量
services:
openclaw:
image: openclaw/openclaw:latest
# 不要用 network_mode: host
environment:
- HTTP_PROXY=http://隧道ID:密码@tps.zdaye.com:8080
- HTTPS_PROXY=http://隧道ID:密码@tps.zdaye.com:8080
特殊场景:如果容器需要访问宿主机的代理服务:
- Docker Desktop:使用
host.docker.internal - Linux Docker:使用宿主机IP(如
172.17.0.1)
六、踩坑五:容器内DNS解析问题
代理配置看起来没问题,环境变量也传进去了,但OpenClaw报错:Error: getaddrinfo ENOTFOUND tps.zdaye.com——这是容器内DNS无法解析代理域名。
解决方案:
方案A:使用IP地址代替域名(联系站大爷客服获取代理入口IP)
方案B:自定义容器DNS
services:
openclaw:
image: openclaw/openclaw:latest
dns:
- 114.114.114.114
- 8.8.8.8
environment:
- HTTP_PROXY=http://隧道ID:密码@tps.zdaye.com:8080
方案C:在容器内测试DNS解析
docker exec openclaw nslookup tps.zdaye.com
七、完整配置模板(复制即用)
version: '3.8'
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "18789:18789"
environment:
# 站大爷隧道代理配置
- HTTP_PROXY=http://你的隧道ID:你的隧道密码@tps.zdaye.com:8080
- HTTPS_PROXY=http://你的隧道ID:你的隧道密码@tps.zdaye.com:8080
- NO_PROXY=localhost,127.0.0.1
# 时区设置
- TZ=Asia/Shanghai
# DNS配置(如果解析有问题,取消注释)
# dns:
# - 114.114.114.114
# - 8.8.8.8
volumes:
- openclaw_data:/root/.openclaw
- openclaw_cache:/root/.cache
# 健康检查(可选)
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789"]
interval: 30s
timeout: 10s
retries: 3
volumes:
openclaw_data:
openclaw_cache:
启动命令:docker-compose up -d
八、网络模式选择建议(总结)
| 网络模式 | 适用场景 | 代理兼容性 | 推荐度 |
| bridge(默认) | 大多数场景,容器需要独立网络 | ⭐⭐⭐⭐⭐ 最佳 | 最推荐 |
| host | 容器需要极致网络性能,不关心隔离 | ⭐⭐ 可能冲突 | 不推荐用于代理场景 |
| none | 完全离线容器 | ❌ 不支持代理 | 不适用 |
| 自定义网络 | 多容器互联 | ⭐⭐⭐⭐ 良好 | 高级用户 |
九、快速排障清单
如果配置完还是不行,按顺序检查:
- [ ] 环境变量是否传入了容器?→
docker exec openclaw env | grep -i proxy - [ ] 代理地址格式是否正确?→ 不要漏掉
http://前缀和认证信息 - [ ] 容器内能否curl通代理?→
docker exec openclaw curl -x http://... https://httpbin.org/ip - [ ] DNS能否解析代理域名?→
docker exec openclaw nslookup tps.zdaye.com - [ ] Docker Desktop是否有
containersProxy配置拦截?→ 检查admin-settings.json - [ ] 是否混用了YAML配置和环境变量?→ 注释掉YAML中的proxy
- [ ] 网络模式是不是
host?→ 改回bridge
总结
Docker部署OpenClaw+站大爷隧道代理,核心就三句话:
- 环境变量传代理,别用YAML配置
- 网络模式用bridge,别用host
- 二选一别混用,环境变量最稳
把这三点记住,基本就不会踩坑了。如果还不行,按上面的排障清单一步步查,总能找到问题。