3.0 KiB
3.0 KiB
#n8n #docker #http-proxy #https-proxy #telegram #xray #v2ray
问题描述
n8n 运行在 Docker 容器内,宿主机已有代理(xray/v2ray 监听 10808 端口),但 n8n 的 Telegram 节点无法连接 api.telegram.org。
排查过程
1. 宿主机可以访问,容器不行
宿主机用 proxychains 可以正常访问 Telegram API:
proxychains4 curl https://api.telegram.org/bot<TOKEN>/getMe
# ✅ 返回 bot 信息
容器内用 Node.js fetch 测试:
node -e "fetch('https://api.telegram.org/...').then(r=>r.text()).then(console.log).catch(console.error)"
# ❌ ETIMEDOUT
2. 发现 docker-compose.yml 中代理地址错误
# ❌ 错误:容器内的 127.0.0.1 是容器自身,不是宿主机
HTTP_PROXY: http://127.0.0.1:10808
HTTPS_PROXY: http://127.0.0.1:10808
3. 修正为 host.docker.internal
# ✅ 正确:通过 host.docker.internal 访问宿主机
HTTP_PROXY: http://host.docker.internal:10808
HTTPS_PROXY: http://host.docker.internal:10808
host.docker.internal 能工作的前提是 docker-compose.yml 中已有:
extra_hosts:
- "host.docker.internal:host-gateway"
4. 确认代理端口可达
在容器内验证连通性:
node -e "
const net = require('net');
const s = net.createConnection(10808, 'host.docker.internal', () => {
console.log('✅ 代理端口可达');
s.destroy();
});
s.on('error', e => console.log('❌ 失败:', e.message));
"
# ✅ 代理端口可达
宿主机确认代理监听地址:
ss -tlnp | grep 10808
# LISTEN *:10808 ← 监听 0.0.0.0,容器可以访问 ✅
5. Node.js 原生 fetch 不读代理环境变量
node fetch 不会自动使用 HTTP_PROXY/HTTPS_PROXY,所以容器内的测试命令显示 ETIMEDOUT 是测试方法有误,并非代理没生效。
n8n 使用 axios,axios 会自动读取代理环境变量,所以 n8n 节点内是正常工作的。
验证方法:直接在 n8n 里用 HTTP Request 节点 访问:
https://api.telegram.org/bot<TOKEN>/getMe
能返回 bot 信息即代理生效 ✅
最终解决方案
docker-compose.yml 关键配置
services:
n8n:
environment:
HTTP_PROXY: http://host.docker.internal:10808 # 指向宿主机代理
HTTPS_PROXY: http://host.docker.internal:10808
NO_PROXY: localhost,127.0.0.1 # 内网地址不走代理
extra_hosts:
- "host.docker.internal:host-gateway" # 必须!映射宿主机 IP
前提条件
| 条件 | 检查命令 |
|---|---|
宿主机代理监听 0.0.0.0(非 127.0.0.1) |
ss -tlnp | grep 10808 |
docker-compose 有 extra_hosts 配置 |
查看 yml 文件 |
重启生效
docker compose down && docker compose up -d
总结
| 问题 | 原因 | 解决 |
|---|---|---|
| 代理不生效 | 127.0.0.1 在容器内指向容器本身 |
改为 host.docker.internal |
| 测试误报 ETIMEDOUT | Node.js 原生 fetch 不读代理环境变量 |
用 n8n HTTP Request 节点直接测试 |