> ## Content Index
> Fetch the complete content index at: https://isoziyuan.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 自建 n8n Webhook 无回调？从 Docker、反向代理到 HTTPS 环境变量的完整排查
- URL: https://isoziyuan.com/p/100103/
- Published: 2026-08-27T11:43:06.000Z
- Updated: 2026-08-27T11:43:04.000Z
- Author: Isoziyuan
- Tags: n8n, 自动化, Docker, 反向代理, 故障排查

不少自建 n8n 实例会出现这样的情况：编辑器可以正常打开，工作流也能手动运行，但第三方平台发送事件后，Webhook 节点始终没有收到数据；或者 n8n 显示的回调地址仍然是 `localhost:5678`、HTTP 地址或错误域名。

这类问题通常不是 Webhook 节点本身失效，而是请求链路中的某一层配置不一致：

```text
第三方平台
    ↓ HTTPS 请求
域名 / CDN / 防火墙
    ↓
Nginx、Caddy 或 Traefik
    ↓ Docker 内部 HTTP
n8n:5678
    ↓
对应的工作流与 Webhook 节点

```

下面按照“先定位请求到了哪里，再修复外部 URL”的思路进行排查。

## 一、先确认使用的是测试 URL 还是生产 URL

n8n 的 Webhook 节点通常会显示两类地址：

```text
测试地址：
https://n8n.example.com/webhook-test/...

生产地址：
https://n8n.example.com/webhook/...

```

二者用途不同。

### 测试 URL

`/webhook-test/` 只适合在编辑器中调试。通常需要先打开 Webhook 节点，点击类似“Listen for test event”或“Execute workflow”的按钮，让 n8n 进入等待状态，然后再发送请求。

如果直接把测试 URL 填到第三方平台，并期待它长期接收回调，通常会出现：

- 编辑器没有处于监听状态；
- 等待状态已经结束；
- 第一次测试成功，后续请求却收不到；
- 重启 n8n 后测试地址不再处于监听状态。

### 生产 URL

正式接收回调应使用 `/webhook/` 地址，并确保对应工作流已经激活或发布。不同 n8n 版本的界面措辞可能略有不同，以当前界面中的“Active”“Activate”或“Publish”为准。

因此，第一步应检查：

1. 第三方平台填写的是 `/webhook/`，不是 `/webhook-test/`；
2. 工作流已经激活或发布；
3. Webhook 节点没有被删除、替换或更改路径；
4. 请求方法与节点设置一致，例如都是 `POST`；
5. 修改工作流后，生产版本是否已经重新发布。

如果第三方平台此前注册的是旧 URL，修改域名或路径后，还需要在对方平台更新回调地址。对于自动注册 Webhook 的触发器节点，通常还需要停用后重新激活工作流，以便重新注册订阅。

---

## 二、用 curl 判断问题发生在哪一层

不要一开始就反复修改 Docker Compose。先从外部网络请求生产 URL，观察 HTTP 状态码。

```bash
curl -i -X POST \
  'https://n8n.example.com/webhook/your-path' \
  -H 'Content-Type: application/json' \
  -d '{"source":"curl","test":true}'

```

最好从不在服务器内网的设备执行，例如本地电脑或另一台云主机。这样才能真实经过公网 DNS、HTTPS 和反向代理。

### 常见结果的含义

| 现象                                   | 通常说明                        |
| ------------------------------------ | --------------------------- |
| DNS 无法解析                             | 域名记录错误或尚未生效                 |
| 连接超时                                 | 安全组、防火墙、端口映射或代理未监听          |
| TLS 证书错误                             | 证书过期、域名不匹配或证书链不完整           |
| 301、302、307、308                      | 存在 HTTP 跳转、路径跳转或登录重定向       |
| 401、403                              | Webhook 鉴权、代理认证、WAF 或访问规则拦截 |
| 404                                  | 路径错误、工作流未激活，或代理改写了路径        |
| 413                                  | 请求体超过反向代理限制                 |
| 502、504                              | 代理无法连接 n8n，或上游超时            |
| n8n 返回 “webhook not registered” 一类信息 | URL 存在，但当前没有对应的生产 Webhook   |
| 请求成功但工作流无记录                          | 需要检查执行模式、队列、节点逻辑和执行日志       |

还可以分别测试首页和 Webhook：

```bash
curl -I https://n8n.example.com/
curl -i -X POST https://n8n.example.com/webhook/your-path

```

编辑器首页能打开，不代表 `/webhook/` 一定被正确转发。有些代理规则只处理了根路径，或者将 Webhook 路径转发到了其他服务。

---

## 三、确认 Docker 中的 n8n 是否真的正常监听

先查看容器状态：

```bash
docker compose ps

```

然后查看实时日志：

```bash
docker compose logs -f n8n

```

如果不是使用 Compose：

```bash
docker ps
docker logs -f n8n

```

重点关注以下问题：

- 容器是否反复重启；
- 端口是否为默认的 `5678`；
- 数据目录是否有权限错误；
- 数据库是否连接失败；
- 是否存在重复的 Webhook 路径；
- 工作流激活时是否注册失败；
- 代理请求到达时，日志中是否有对应记录。

### 在 Docker 网络内部测试 n8n

如果 Nginx 也运行在 Docker 中，可以从代理容器测试：

```bash
docker exec -it nginx sh

```

进入后，根据容器内可用工具执行：

```bash
wget -S -O- http://n8n:5678/

```

或者：

```bash
curl -I http://n8n:5678/

```

这里的 `n8n` 应当是 Compose 服务名，并且代理与 n8n 必须加入同一个 Docker 网络。

如果代理运行在宿主机，而 n8n 映射到了本机回环地址，可以测试：

```bash
curl -I http://127.0.0.1:5678/

```

判断原则很简单：

- Docker 内部访问失败：先修复容器、网络或监听问题；
- Docker 内部成功，公网失败：重点检查反向代理、HTTPS、防火墙和 DNS；
- 公网请求能到达 n8n，但提示 Webhook 不存在：重点检查 URL、请求方法和工作流状态。

---

## 四、正确理解 `WEBHOOK_URL` 的作用

反向代理场景中，n8n 容器内部通常使用 HTTP：

```text
http://n8n:5678

```

但外部访问地址是：

```text
https://n8n.example.com

```

n8n 仅根据容器内部监听信息，未必能正确推断外部协议和域名。因此需要显式设置：

```yaml
WEBHOOK_URL: https://n8n.example.com/

```

`WEBHOOK_URL` 的作用是告诉 n8n：外部系统应通过这个基础地址访问 Webhook。

它主要影响：

- Webhook 节点显示的生产 URL；
- 部分触发器节点向第三方平台注册的回调地址；
- n8n 对外生成的 Webhook 基础地址。

但要注意：

> `WEBHOOK_URL` 不会自动配置 DNS、申请证书、开放防火墙，也不会替代反向代理。

如果域名没有指向服务器，或者 Nginx 没有转发请求，仅设置这个变量仍然无法收到回调。

建议 URL 使用完整 HTTPS 地址，并保留末尾斜杠：

```yaml
WEBHOOK_URL: https://n8n.example.com/

```

不建议填写：

```yaml
WEBHOOK_URL: http://localhost:5678/
WEBHOOK_URL: http://n8n:5678/
WEBHOOK_URL: https://192.168.1.10/

```

除非这些地址确实能够被发送回调的第三方平台访问。

---

## 五、推荐的 Docker Compose 配置

以下示例采用“宿主机或独立代理负责 HTTPS，n8n 容器内部使用 HTTP”的部署方式。

```yaml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: unless-stopped

    environment:
      N8N_HOST: n8n.example.com
      N8N_PORT: 5678
      N8N_PROTOCOL: https

      WEBHOOK_URL: https://n8n.example.com/
      N8N_EDITOR_BASE_URL: https://n8n.example.com/

      N8N_PROXY_HOPS: 1

      GENERIC_TIMEZONE: Asia/Shanghai
      TZ: Asia/Shanghai

      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"

    volumes:
      - n8n_data:/home/node/.n8n

    ports:
      - "127.0.0.1:5678:5678"

volumes:
  n8n_data:

```

将示例中的 `n8n.example.com` 替换为实际域名。

### 这些变量分别解决什么问题

#### `N8N_HOST`

指定 n8n 对外使用的主机名：

```yaml
N8N_HOST: n8n.example.com

```

不要在这里填写 `https://`，也不要添加路径。

#### `N8N_PROTOCOL`

外部用户通过 HTTPS 访问时设置为：

```yaml
N8N_PROTOCOL: https

```

这不代表 n8n 容器自身必须监听 HTTPS。常见做法仍然是由反向代理终止 TLS，容器内部使用 HTTP。

#### `WEBHOOK_URL`

明确指定外部 Webhook 基础地址：

```yaml
WEBHOOK_URL: https://n8n.example.com/

```

这是“n8n 显示 localhost Webhook”或“第三方注册到了 HTTP 地址”时最关键的变量。

#### `N8N_EDITOR_BASE_URL`

用于明确编辑器的外部访问地址：

```yaml
N8N_EDITOR_BASE_URL: https://n8n.example.com/

```

它与 `WEBHOOK_URL` 的职责不同：前者偏向编辑器访问地址，后者偏向 Webhook 回调地址。在同一域名部署时，两者通常保持一致。

#### `N8N_PROXY_HOPS`

n8n 位于反向代理后方时，需要正确处理受信代理传入的转发头：

```yaml
N8N_PROXY_HOPS: 1

```

这里不是永远固定为 `1`，而是取决于真实代理层数。例如：

```text
客户端 → Nginx → n8n

```

通常是一层。

如果链路是：

```text
客户端 → CDN/负载均衡 → Nginx → n8n

```

则需要结合实际架构和 n8n 当前版本文档确定代理跳数。不要为了“快速修好”盲目设置过大的值，否则可能错误信任客户端伪造的转发头。

### 不建议把 5678 直接暴露到公网

如果反向代理运行在宿主机，可以绑定到本机回环地址：

```yaml
ports:
  - "127.0.0.1:5678:5678"

```

如果反向代理也运行在同一个 Docker 网络中，甚至可以不声明 `ports`，只使用：

```yaml
expose:
  - "5678"

```

然后由代理通过服务名访问：

```text
http://n8n:5678

```

这比直接使用下面的配置更安全：

```yaml
ports:
  - "5678:5678"

```

后者可能让 n8n 绕过 HTTPS 和反向代理直接暴露在公网，具体还取决于宿主机防火墙规则。

---

## 六、Nginx 反向代理参考配置

如果 Nginx 运行在宿主机，而 n8n 映射到 `127.0.0.1:5678`，可以使用类似配置：

```nginx
server {
    listen 80;
    listen [::]:80;
    server_name n8n.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name n8n.example.com;

    ssl_certificate     /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;

    client_max_body_size 16m;

    location / {
        proxy_pass http://127.0.0.1:5678;

        proxy_http_version 1.1;

        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-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }
}

```

修改配置后先检查语法：

```bash
sudo nginx -t

```

确认无误后重新加载：

```bash
sudo systemctl reload nginx

```

### 必须保留的转发信息

至少应正确传递：

```nginx
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

```

其中 `X-Forwarded-Proto` 尤其重要。外部请求明明是 HTTPS，但 n8n 容器收到的是来自 Nginx 的 HTTP；如果代理没有告诉 n8n 原始协议是 HTTPS，就可能生成错误的 HTTP 地址或产生安全 Cookie、重定向方面的问题。

### 不要意外删除 Webhook 路径

下面两种 `proxy_pass` 写法在涉及路径拼接时可能产生不同结果：

```nginx
proxy_pass http://127.0.0.1:5678;

```

```nginx
proxy_pass http://127.0.0.1:5678/;

```

当 `location` 使用子路径时，末尾斜杠会影响路径替换规则。最稳妥的方案是给 n8n 使用独立子域名：

```text
https://n8n.example.com/

```

而不是部署到：

```text
https://example.com/n8n/

```

如果必须部署在子路径下，还需要同步检查 n8n 路径配置、编辑器资源路径、Webhook URL 和代理改写规则，不能只修改 Nginx 的 `location`。

---

## 七、修改环境变量后必须重建容器

修改 `.env` 或 `compose.yaml` 后，仅重启容器有时不会应用新的容器环境配置。建议执行：

```bash
docker compose up -d --force-recreate

```

然后确认容器实际获得的环境变量：

```bash
docker compose exec n8n env | grep -E \
'N8N_HOST|N8N_PORT|N8N_PROTOCOL|WEBHOOK_URL|N8N_EDITOR_BASE_URL|N8N_PROXY_HOPS'

```

预期能看到类似结果：

```text
N8N_HOST=n8n.example.com
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.example.com/
N8N_EDITOR_BASE_URL=https://n8n.example.com/
N8N_PROXY_HOPS=1

```

如果输出仍然是旧值，检查：

- 是否修改了错误的 Compose 文件；
- 是否使用了多个 `-f` 配置文件；
- `.env` 是否位于正确目录；
- 变量是否被宿主机环境覆盖；
- 是否存在旧容器；
- YAML 缩进是否正确。

可以查看 Compose 展开后的最终配置：

```bash
docker compose config

```

注意该命令可能输出解析后的敏感变量，不要将完整结果公开发布。

---

## 八、HTTPS 正常打开，不代表回调一定能通过

第三方平台通常对 Webhook HTTPS 有更严格的要求。浏览器能访问，不代表平台一定接受。

需要检查以下项目。

### 1\. 证书域名是否匹配

证书必须覆盖实际回调域名，例如：

```text
n8n.example.com

```

不能使用只覆盖 `example.com`、但不包含该子域名的证书。

查看证书信息：

```bash
openssl s_client \
  -connect n8n.example.com:443 \
  -servername n8n.example.com </dev/null

```

也可以进一步检查证书主题、签发者和有效期：

```bash
echo | openssl s_client \
  -connect n8n.example.com:443 \
  -servername n8n.example.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

```

### 2\. 证书链是否完整

服务器一般应提供完整证书链。Nginx 使用 Let’s Encrypt 时，通常应配置 `fullchain.pem`，而不是只配置单张站点证书。

### 3\. 回调是否发生了重定向

第三方平台未必会跟随重定向，尤其是签名校验严格的平台。直接把 HTTPS 最终地址注册为回调 URL，不要依赖：

```text
HTTP → HTTPS
旧域名 → 新域名
无斜杠 → 有斜杠
登录页 → Webhook

```

检查是否重定向：

```bash
curl -I https://n8n.example.com/webhook/your-path

```

对于只允许 `POST` 的 Webhook，应使用实际请求方法测试，而不是仅依赖 `HEAD`：

```bash
curl -i -X POST \
  https://n8n.example.com/webhook/your-path \
  -H 'Content-Type: application/json' \
  -d '{}'

```

### 4\. 防火墙是否开放 443

检查云平台安全组、宿主机防火墙以及前置负载均衡规则。一般只需向公网开放：

- TCP 80：证书签发或跳转，可根据部署方式决定；
- TCP 443：正式 HTTPS 访问。

没有必要把 n8n 的 `5678` 端口直接开放给公网。

---

## 九、代理和 WAF 容易忽略的拦截点

如果前面还有 CDN、Web 应用防火墙或零信任访问网关，需要额外检查。

### 登录保护拦截了 Webhook

如果在整个 n8n 域名前增加了统一登录认证，第三方平台请求 Webhook 时可能被重定向到登录页或直接收到 `401`。

表现通常是：

```text
第三方平台 → /webhook/... → 登录页

```

Webhook 机器请求无法像用户一样完成交互式登录。需要在安全策略中为必要的 Webhook 路径设置合适的机器访问规则，同时通过以下方式保护接口：

- Webhook 节点自带的鉴权方式；
- 随机且不可猜测的路径；
- 请求头令牌；
- 第三方平台提供的签名校验；
- 来源 IP 限制，但仅在对方提供稳定出口地址时使用。

不要仅依赖“URL 没公开”作为唯一安全措施。

### WAF 将 JSON 或表单误判为攻击

如果 n8n 日志中完全没有请求，但 CDN 或 WAF 日志中出现 `403`，需要检查托管规则、速率限制和请求体检测策略。

不要直接关闭所有安全规则。应针对确定的回调路径、来源和请求特征设置最小范围的例外。

### 请求体过大

Nginx 默认请求体限制可能无法满足包含文件、长文本或大 JSON 的回调。日志中常见：

```text
client intended to send too large body

```

可以按实际需求调整：

```nginx
client_max_body_size 16m;

```

不要无上限放大。对于大文件，更合理的方式通常是让第三方只发送文件 URL，再由 n8n 按权限下载。

### 上游响应超时

某些第三方平台要求 Webhook 很快返回成功状态。如果工作流收到请求后执行耗时操作，平台可能认为回调失败并重复发送。

可考虑让 Webhook 尽快返回，再继续执行后续逻辑。具体响应模式应在 Webhook 节点中根据业务需求设置，并配合幂等机制防止重复处理。

---

## 十、看到请求但工作流没按预期执行

当代理日志和 n8n 日志都能看到请求时，问题已经不再是“公网无法到达”，而应检查工作流本身。

### 请求方法不一致

Webhook 节点配置为：

```text
POST

```

第三方平台却发送：

```text
GET

```

即使路径完全相同，也不会匹配正确的 Webhook。

使用详细模式确认请求：

```bash
curl -v -X POST https://n8n.example.com/webhook/your-path

```

### 路径大小写或斜杠不一致

检查以下差异：

```text
/webhook/order-created
/webhook/Order-Created
/webhook/order-created/
/webhook/order_created

```

不要假设代理、n8n 或第三方平台会自动将它们视为同一路径。

### 同一路径存在冲突

多个工作流使用相同请求方法和生产 Webhook 路径，可能导致注册冲突或激活失败。检查 n8n 日志，并为每个入口使用唯一、清晰的路径。

### Webhook 鉴权不匹配

如果节点启用了 Basic Auth、Header Auth 或其他认证，curl 测试和第三方平台也必须发送对应凭据。

例如使用请求头：

```bash
curl -i -X POST \
  'https://n8n.example.com/webhook/your-path' \
  -H 'Content-Type: application/json' \
  -H 'X-Webhook-Token: replace-with-real-token' \
  -d '{"test":true}'

```

不要把密钥直接硬编码在公开的工作流截图、Compose 文件或代码仓库中。

### 回调签名验证失败

很多平台会发送时间戳、签名和原始请求体。签名验证应严格按照对方官方文档处理，尤其注意：

- 是否使用原始请求体；
- JSON 是否被重新序列化；
- 字符编码是否一致；
- 时间戳是否超过允许范围；
- 密钥是否来自正确环境；
- 请求头名称是否区分大小写或被代理过滤。

如果签名失败，应明确返回鉴权失败，而不是为了让流程“先跑起来”长期关闭签名验证。

---

## 十一、通过代理访问日志确定请求是否到达

为 Nginx 查看实时访问日志：

```bash
sudo tail -f /var/log/nginx/access.log

```

同时查看错误日志：

```bash
sudo tail -f /var/log/nginx/error.log

```

然后让第三方平台重新发送回调，或使用 curl 请求。

可以根据日志快速分层判断：

### 访问日志中没有请求

可能原因：

- 第三方平台根本没有发送；
- 域名解析到错误服务器；
- CDN、负载均衡或防火墙提前拦截；
- 使用了旧回调 URL；
- 请求走了 IPv6，但服务器 IPv6 配置不正确。

检查 DNS：

```bash
dig +short A n8n.example.com
dig +short AAAA n8n.example.com

```

如果存在 `AAAA` 记录，但服务器没有正确提供 IPv6 服务，部分平台可能优先尝试 IPv6 并失败。此时应修复 IPv6 链路或删除不正确的 `AAAA` 记录。

### Nginx 有请求，n8n 没有日志

可能原因：

- `proxy_pass` 指向错误地址；
- Nginx 匹配了其他 `location`；
- 路径被改写；
- 请求被 Nginx 直接返回；
- 上游连接失败。

### n8n 有请求，但没有成功执行

可能原因：

- 工作流未激活或未发布；
- Webhook 路径、方法不匹配；
- 节点认证失败；
- 工作流执行报错；
- 执行数据保留策略导致界面中看不到预期记录。

---

## 十二、一套高效的排查顺序

遇到 n8n Webhook 收不到回调时，可以按下面顺序执行，避免同时修改多个变量。

### 第一步：核对 URL

确认第三方平台使用：

```text
https://实际域名/webhook/实际路径

```

而不是：

```text
http://localhost:5678/...
http://容器名:5678/...
https://实际域名/webhook-test/...

```

### 第二步：确认工作流状态

- 使用生产 URL；
- 工作流已激活或发布；
- 请求方法正确；
- 节点路径没有变化；
- 自动注册型触发器已重新激活。

### 第三步：从公网 curl

```bash
curl -i -X POST \
  https://n8n.example.com/webhook/your-path \
  -H 'Content-Type: application/json' \
  -d '{"test":true}'

```

记录状态码、响应头和响应体。

### 第四步：检查三层日志

依次查看：

1. CDN、负载均衡或 WAF 日志；
2. Nginx 访问日志与错误日志；
3. n8n 容器日志。

请求在哪一层消失，问题就优先在哪一层处理。

### 第五步：验证内部连通性

```bash
curl -I http://127.0.0.1:5678/

```

或者在 Docker 网络中：

```bash
curl -I http://n8n:5678/

```

### 第六步：检查关键环境变量

至少核对：

```text
N8N_HOST
N8N_PROTOCOL
WEBHOOK_URL
N8N_EDITOR_BASE_URL
N8N_PROXY_HOPS

```

### 第七步：重建容器

```bash
docker compose up -d --force-recreate

```

然后再次查看 n8n 界面中显示的生产 Webhook URL。

### 第八步：重新注册外部回调

- 在第三方平台保存新的 HTTPS URL；
- 必要时删除旧订阅后重新创建；
- 自动注册型触发器停用后重新激活；
- 使用平台提供的“测试回调”或“重新发送”功能验证。

---

## 十三、安全部署时还应完成的事项

修复回调后，不要停留在“能用即可”的状态。自建 n8n 往往保存 API 密钥、数据库密码和业务数据，应至少做好以下措施。

### 使用固定的加密密钥

配置一个足够随机且长期保存的密钥：

```yaml
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}

```

可以生成随机值：

```bash
openssl rand -hex 32

```

妥善备份该密钥，不要提交到 Git 仓库，也不要在迁移时随意更换。否则已有凭据可能无法正常解密。

### 持久化 n8n 数据目录

```yaml
volumes:
  - n8n_data:/home/node/.n8n

```

同时对数据库和数据卷进行定期备份。容器可重建不等于业务数据可恢复。

### 不直接公开 5678

让外部请求统一经过 HTTPS 反向代理，只对公网开放必要端口。

### 限制编辑器访问

Webhook 必须被第三方平台访问，但编辑器不一定需要对整个公网开放。可以结合：

- VPN；
- 固定办公 IP；
- 零信任访问控制；
- 独立的编辑器访问策略；
- n8n 自身的用户管理与强密码。

配置额外访问控制时，务必确认不会把第三方 Webhook 一起重定向到交互式登录页面。

### 更新前先备份并查看变更说明

不要在生产环境中长期依赖不可控的自动更新。即使 Compose 示例使用了 `latest`，正式部署也更适合根据团队维护策略固定经过验证的版本，在升级前备份数据库、加密密钥和数据目录，并阅读对应版本的变更说明。

---

## 最终核对清单

如果下面各项全部成立，n8n Webhook 通常就能稳定接收外部回调：

- \[ \] 域名 A/AAAA 记录指向正确入口；
- \[ \] HTTPS 证书有效、域名匹配且证书链完整；
- \[ \] 公网 TCP 443 可访问；
- \[ \] Nginx 能连接 n8n 的 `5678` 端口；
- \[ \] 代理没有删除或错误改写 `/webhook/` 路径；
- \[ \] `Host`、`X-Forwarded-For`、`X-Forwarded-Proto` 正确传递；
- \[ \] `WEBHOOK_URL` 是完整的公网 HTTPS 地址；
- \[ \] `N8N_HOST` 和 `N8N_PROTOCOL` 与外部地址一致；
- \[ \] `N8N_PROXY_HOPS` 与实际代理链路匹配；
- \[ \] 修改环境变量后已经重建容器；
- \[ \] 正式回调使用 `/webhook/`，而不是 `/webhook-test/`；
- \[ \] 工作流已经激活或发布；
- \[ \] 请求方法、路径和鉴权配置完全一致；
- \[ \] 第三方平台已经更新或重新注册回调地址；
- \[ \] CDN、WAF 或统一登录没有拦截 Webhook；
- \[ \] Nginx 和 n8n 日志能看到同一次请求；
- \[ \] n8n 的数据目录、数据库和加密密钥已有备份。

最关键的排查原则是：**不要只看 n8n 编辑器中的 URL，也不要只看“网页能否打开”，而要从公网请求开始，沿着 DNS、HTTPS、反向代理、Docker 网络和工作流状态逐层确认。** 一旦确定请求在哪一层消失，问题通常就能快速收敛。