配置反向代理下的n8n Webhook URL

在使用 n8n 自动化平台时,Webhook 是一个核心功能,它允许 n8n 接收来自外部服务的实时事件。然而,当 n8n 部署在反向代理(如 Nginx、Apache 或 Caddy)之后时,正确配置 Webhook URL 变得至关重要。本文将详细解释为何会出现配置问题,并提供确保 Webhook 正常工作的关键环境变量和反向代理设置。

理解问题:反向代理与n8n Webhook URL的冲突

n8n 默认情况下会尝试通过结合其内部协议 (N8N_PROTOCOL)、主机 (N8N_HOST) 和端口 (N8N_PORT) 来自动构建 Webhook URL。这种方法在 n8n 直接暴露在公网环境下时运作良好。

然而,当 n8n 运行在反向代理之后时,情况就会变得复杂。反向代理充当 n8n 服务器和外部客户端之间的中间层。例如,n8n 可能在服务器内部的 5678 端口上运行,但反向代理将其暴露给互联网时可能使用标准的 443 端口(用于 HTTPS)或 80 端口(用于 HTTP)。这意味着 n8n 内部生成的 URL(例如 http://localhost:5678/webhook/abcd)与用户或外部服务实际访问的外部 URL(例如 https://n8n.example.com/webhook/abcd)不匹配。

这种不匹配会导致以下问题:

  • 用户界面显示错误: n8n 编辑器中显示的 Webhook URL 将是内部地址,用户无法直接访问。
  • 外部服务注册失败: 当 n8n 尝试向外部服务(如 GitHub、Stripe 等)注册 Webhook 时,它会提供一个不正确的内部 URL,导致注册失败或事件无法送达。

为了解决这些问题,我们需要明确地告诉 n8n 其外部可访问的地址,并确保反向代理正确地将原始请求信息传递给 n8n。

核心解决方案:环境变量配置

在 n8n 部署中,通过设置特定的环境变量,可以有效地解决反向代理带来的 Webhook URL 问题。

1. 设置 WEBHOOK_URL 环境变量

这是最直接且最重要的配置。WEBHOOK_URL 环境变量允许您手动指定 n8n 公开可访问的完整基准 URL。n8n 将使用此值来生成所有 Webhook URL,无论是在用户界面显示,还是在与外部服务通信时。

配置示例: 假设您的 n8n 实例可以通过 https://n8n.example.com/ 访问,您应该设置:

export WEBHOOK_URL=https://n8n.example.com/

请确保此 URL 包含协议(http://https://)并且以斜杠结尾,以便 n8n 可以正确地在其后拼接 Webhook 路径。

2. 设置 N8N_PROXY_HOPS 环境变量

N8N_PROXY_HOPS 环境变量告诉 n8n 它位于多少个反向代理之后。这个设置非常重要,因为它影响 n8n 如何信任和解析由反向代理发送的 X-Forwarded-* HTTP 请求头。

配置示例: 如果 n8n 位于一个反向代理之后(这是最常见的情况),您应该设置:

export N8N_PROXY_HOPS=1

这个值告诉 n8n,它应该信任第一个 X-Forwarded-* 头中包含的信息,将其视作真实的客户端或原始请求信息。如果您的架构中有多个反向代理(例如,一个CDN在前面,然后是一个内部Nginx代理),您需要根据实际的代理跳数来调整此值。

反向代理配置:传递HTTP头

除了 n8n 自身的环境变量设置外,反向代理本身也必须正确配置,以将原始请求的关键信息传递给 n8n。这些信息通常通过 X-Forwarded-* 系列 HTTP 头进行传递。确保在请求路径上的最后一个反向代理上设置以下 HTTP 头。

1. X-Forwarded-For

  • 作用: 这个头用于标识通过 HTTP 代理或负载均衡器连接到 Web 服务器的客户端的原始 IP 地址。
  • 重要性: 对于 n8n 来说,了解客户端的真实 IP 地址对于日志记录、安全分析以及某些基于 IP 的业务逻辑至关重要。
  • 代理设置示例 (Nginx):
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
    此设置会追加客户端 IP 到 X-Forwarded-For 头,如果该头不存在则创建。

2. X-Forwarded-Host

  • 作用: 这个头用于标识客户端在原始请求中指定的主机名。
  • 重要性: 在 n8n 后端,这个头可以帮助 n8n 确定原始请求的目标主机,这对于支持多个域名或正确生成特定于域名的内容非常有用。
  • 代理设置示例 (Nginx):
    proxy_set_header X-Forwarded-Host $host;
    
    这将把原始请求中的 Host 头传递给 n8n。

3. X-Forwarded-Proto

  • 作用: 这个头用于标识客户端用于连接到反向代理的原始协议(HTTP 或 HTTPS)。
  • 重要性: n8n 需要知道客户端是使用 HTTP 还是 HTTPS 协议连接到反向代理的,以便生成带有正确协议(例如 https:// 而不是 http://)的链接和 Webhook URL。这对于确保安全性(例如强制 HTTPS)以及避免混合内容警告至关重要。
  • 代理设置示例 (Nginx):
    proxy_set_header X-Forwarded-Proto $scheme;
    
    $scheme 变量会根据原始请求是 HTTP 还是 HTTPS 来设置 httphttps

综合配置示例 (Docker Compose 环境)

在 Docker Compose 文件中,您可以在 environment 部分设置这些变量:

version: '3.8'
services:
  n8n:
    image: n8n.io/n8n
    restart: always
    ports:
      - "5678:5678" # 仅用于内部访问或调试,外部通过代理访问
    environment:
      - N8N_PROTOCOL=http # n8n 内部运行协议,与反向代理前的协议保持一致
      - N8N_HOST=localhost # n8n 内部主机名,与反向代理前的 IP 或 hostname 保持一致
      - N8N_PORT=5678 # n8n 内部监听端口
      - WEBHOOK_URL=https://n8n.example.com/ # 外部访问的完整 URL
      - N8N_PROXY_HOPS=1 # 告知 n8n 位于一个反向代理之后

同时,对应的 Nginx 反向代理配置可能如下所示(简化版):

server {
    listen 80;
    server_name n8n.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name n8n.example.com;

    ssl_certificate /etc/nginx/certs/n8n.example.com.crt;
    ssl_certificate_key /etc/nginx/certs/n8n.example.com.key;

    location / {
        proxy_pass http://localhost:5678/; # 假设 n8n 容器在本地 5678 端口运行
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

注意: N8N_PROTOCOL, N8N_HOST, N8N_PORT 仍然需要设置,它们定义了 n8n 内部监听的地址,而 WEBHOOK_URL 则定义了外部可访问的地址。N8N_PROXY_HOPSX-Forwarded-* 头则用于桥接内部和外部信息。

总结

正确配置反向代理下的 n8n Webhook URL 对于确保工作流的稳定运行至关重要。通过设置 WEBHOOK_URLN8N_PROXY_HOPS 环境变量,并确保反向代理正确传递 X-Forwarded-ForX-Forwarded-HostX-Forwarded-Proto 等 HTTP 头,您可以消除内部和外部 URL 不匹配的问题,让 n8n Webhook 能够可靠地接收和处理事件。务必根据您的具体部署环境调整这些设置。

查看更多详情