Docker 部署 n8n 自动化工作流:Webhook 本地调试完整流程

Docker 部署 n8n 自动化工作流:Webhook 回调地址本地调试完整流程

做 n8n 工作流时,最容易卡住的不是节点怎么拖,而是 Webhook 回调地址怎么让外部平台访问到。

本地浏览器打开 http://localhost:5678 没问题,curl 也能打通;可一到 GitHub、飞书、企业微信、支付回调这类第三方平台,回调地址就不能再写 localhost 了。第三方服务在它自己的服务器上发请求,访问不到你电脑里的本地端口。

这篇就按一条完整链路来走:用 Docker Compose 把 n8n 跑起来,创建 Webhook 节点,本地先用 curl 验证,再用 cpolar 把 5678 映射成 HTTPS 地址,后面把公网回调地址填到第三方平台里,并在 n8n 执行记录里确认请求已经进来。

n8n Webhook 本地调试与公网回调链路图

图1:n8n Webhook 本地调试与公网回调链路图。

1 什么是 n8n Webhook?

n8n 是一个自托管自动化工作流工具,可以把不同系统里的事件串起来。比如收到一条表单提交,就自动写入数据库;代码仓库有 push,就自动通知群;支付平台回调成功,就触发后续发货流程。

Webhook 节点在这里负责“接电话”。外部系统把 HTTP 请求打到 n8n 的 Webhook 地址,n8n 收到请求后启动工作流,后面的节点再继续处理数据。

这里要分清两个地址:

  • Test URL:调试时使用,需要在编辑器里点 Listen for test event 或执行工作流后才会监听。
  • Production URL:正式使用时使用,需要工作流处于激活状态。

这个区别很关键。很多人本地调试能通,填到第三方平台就没反应,原因就是拿 Test URL 当长期回调地址用了,或者忘了激活工作流。

2 环境准备:确认 Docker 与端口

这篇默认你已经有一台能运行 Docker 的电脑或服务器,Windows、macOS、Linux 都可以。n8n 默认监听 5678 端口,后面 cpolar 也会映射这个端口。

先检查 Docker 和 Docker Compose:

docker --version
docker compose version

能看到版本号再继续。这里别急着拉镜像,先确认本机没有别的服务占用 5678

Linux / macOS 可以这样查:

lsof -i :5678

如果有输出,说明端口已经被占用。要么停掉占用端口的服务,要么把 n8n 映射到别的宿主机端口。为了后面的回调地址不绕,这篇统一使用 5678:5678

Docker Compose 部署 n8n 与 cpolar 映射 5678 端口示意图

图2:Docker Compose 部署 n8n,并通过 cpolar 将本地 5678 端口映射为 HTTPS 回调地址。

3 使用 Docker Compose 部署 n8n

先建一个单独目录,后面配置文件、数据卷都放在这里,排错时不容易乱。

mkdir -p ~/n8n-webhook-demo
cd ~/n8n-webhook-demo

创建 .env 文件。这里先写本地访问配置,等 cpolar 生成 HTTPS 地址后,再回来补 WEBHOOK_URL

cat > .env <<'EOF'
GENERIC_TIMEZONE=Asia/Shanghai
TZ=Asia/Shanghai
N8N_PORT=5678
WEBHOOK_URL=http://localhost:5678/
EOF

再创建 docker-compose.yml

cat > docker-compose.yml <<'EOF'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    container_name: n8n-webhook-demo
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${TZ}
      - N8N_PORT=${N8N_PORT}
      - WEBHOOK_URL=${WEBHOOK_URL}
      - N8N_PROXY_HOPS=1
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_RUNNERS_ENABLED=true
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:
EOF

启动 n8n:

docker compose up -d

看容器状态:

docker compose ps

再看日志,确认服务已经监听:

docker compose logs -f n8n

看到 n8n 启动完成后,在浏览器打开:

http://localhost:5678

第一次进入会要求创建 Owner 账号。这里用你自己的邮箱和密码就行,不要把测试密码写进脚本里。做完这一步,后面所有工作流、凭据、执行记录都会保存在 Docker volume n8n_data 里。

如果页面打不开,先别怀疑 Webhook。按顺序检查三件事:容器是否 Up、日志里有没有报错、5678 端口是否被占用。

4 创建 Webhook 节点并本地 curl 调试

进入 n8n 后,新建一个 workflow。这个工作流只做一件事:接收一个 POST 请求,并把请求内容显示出来。

添加节点时选择 Webhook,建议这样填:

  • HTTP Method:POST
  • Path:local-demo
  • Authentication:None
  • Respond:Immediately
  • Response Code:200

这里先用 None 是为了把链路跑通。正式接第三方平台时,再按平台能力加 Header Auth、Basic Auth 或签名校验。不要一开始就把鉴权、业务处理、回调调试混在一起,不然出问题时很难判断是哪一层断了。

配置完成后,点 Webhook 节点里的 Listen for test event。这一步不是摆设,Test URL 只有在监听测试事件时才接收请求。

本机终端执行:

curl -X POST 'http://localhost:5678/webhook-test/local-demo' \
  -H 'Content-Type: application/json' \
  -d '{"source":"curl","event":"local_test","amount":99}'

回到 n8n 编辑器,应该能看到这次请求的数据,包括 headers、body、query 等信息。这里的目标不是做业务,而是确认“本机 curl → n8n Webhook 节点”这段链路已经打通。

如果收不到数据,优先检查:

  • Webhook 节点是不是还在 Listen for test event 状态。
  • curl 里的路径是不是 /webhook-test/local-demo,不是 /webhook/local-demo
  • 节点 Method 是否是 POST,curl 是否也用了 -X POST

本地测试通过后,把工作流保存。接第三方平台前,建议再加一个很简单的后续节点,比如 SetEdit Fields,先把请求里的关键字段整理出来。调试阶段节点越少,越容易定位问题。

5 用 cpolar 映射 5678 生成 HTTPS 回调地址

现在本地 n8n 已经能收请求,但外部平台访问不到 localhost。这一步用 cpolar 给本机 5678 端口开一个 HTTP 隧道,拿到公网 HTTPS 地址。

如果你是 Linux 机器,可以用官方一键脚本安装:

curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash

macOS 可以用 Homebrew:

brew tap probezy/core && brew install cpolar

安装后先确认命令可用:

cpolar version

登录账号有两种方式:打开本地 Web UI 登录,或者用后台里的 authtoken 绑定。Web UI 默认地址是:

http://127.0.0.1:9200

这篇走临时调试流程,直接用命令行映射 n8n 端口:

cpolar http 5678

终端里会输出公网访问地址。HTTP 隧道一般会同时给出 httphttps 地址,Webhook 回调优先复制 https 地址,例如:

https://xxxx.cpolar.cn

上面的示意图也适用于这一步:确认 cpolar 将本地 5678 映射到当前可用的 HTTPS 地址后,再继续更新 n8n 配置。

提醒一句:免费随机地址会变化,适合开发调试和临时联调。如果要给长期运行的第三方回调使用,建议使用固定二级子域名,并在 n8n 配置里写固定的 WEBHOOK_URL

6 更新 n8n 的 WEBHOOK_URL,让编辑器显示公网地址

n8n 生成 Webhook URL 时会读取 WEBHOOK_URL。刚才 .env 里还是 http://localhost:5678/,外部平台不能用这个地址。

把 cpolar 的 HTTPS 地址写进 .env。注意末尾保留 /

cd ~/n8n-webhook-demo

cp .env .env.bak

cat > .env <<'EOF'
GENERIC_TIMEZONE=Asia/Shanghai
TZ=Asia/Shanghai
N8N_PORT=5678
WEBHOOK_URL=https://xxxx.cpolar.cn/
EOF

https://xxxx.cpolar.cn/ 换成你自己终端里看到的 HTTPS 地址。这里别填 http://localhost:5678/,也别把路径 /webhook/local-demo 一起写进 WEBHOOK_URL。这个变量只写 n8n 的外部访问根地址。

重启容器让配置生效:

docker compose up -d

重新打开 n8n 编辑器,Webhook 节点里显示的 Test URL 和 Production URL 会变成公网 HTTPS 开头。

如果页面里还显示 localhost,先刷新浏览器,再检查容器环境变量:

docker compose exec n8n printenv WEBHOOK_URL

输出应该是刚才写入的 HTTPS 根地址。

7 配置第三方回调并查看执行记录

第三方平台接回调时,建议直接用 Production URL。原因很简单:Test URL 依赖编辑器里的监听状态,不适合长期接外部事件。

在 n8n 里切到 Webhook 节点的 Production URL,确认地址格式类似:

https://xxxx.cpolar.cn/webhook/local-demo

保存工作流,并把右上角开关切到激活状态。没有激活时,Production URL 不会按正式工作流接收请求。

为了模拟第三方平台,可以先用公网地址再打一遍:

curl -X POST 'https://xxxx.cpolar.cn/webhook/local-demo' \
  -H 'Content-Type: application/json' \
  -d '{"source":"public_curl","event":"production_test","order_id":"A1001"}'

这次不要盯着编辑器画布等数据弹出来。Production URL 的执行数据在工作流的 Executions 里看。打开对应执行记录,可以看到请求体、响应状态,以及后续节点的处理结果。

确认公网 curl 能触发后,再去第三方平台填写回调地址。不同平台入口名称不一样,常见叫法包括 Webhook URL、回调地址、事件订阅地址、通知地址。填写时只填完整 URL,不要额外加空格。

如果第三方平台要求校验 token 或签名,建议先完成平台的校验流程,再打开业务节点。调试时保留一条最简单的记录节点,能省掉很多来回猜的时间。

8 排错与安全提醒

Webhook 调试别一上来就改配置,先按链路分段看。

本地访问 n8n 不通,查 Docker:

docker compose ps
docker compose logs --tail=100 n8n
lsof -i :5678

本地 curl 不进 Webhook,查 n8n 节点:

curl -i -X POST 'http://localhost:5678/webhook-test/local-demo' \
  -H 'Content-Type: application/json' \
  -d '{"debug":true}'

重点看 Method、Path、Test URL 是否处于监听状态。

公网地址打不开,查 cpolar:

cpolar http 5678

同时打开本地 Web UI:

http://127.0.0.1:9200

状态 → 在线隧道列表 里确认隧道在线,并复制当前 HTTPS 地址。做 Webhook 调试时,也可以打开 http://localhost:4040 查看 HTTP 请求是否打进隧道,这对排查“第三方平台到底有没有发请求”很有用。

Production URL 没触发,查工作流状态:

  • 工作流是否已保存。
  • 右上角是否已激活。
  • 第三方平台填的是 /webhook/local-demo,不是 /webhook-test/local-demo
  • WEBHOOK_URL 是否是当前可用的 HTTPS 根地址。

安全上也别偷懒。n8n 能连很多系统,里面会保存凭据和自动化动作,不要把管理页面长期裸露在公网里。临时调试结束后,可以关闭 cpolar 前台进程;长期使用时,至少要启用强密码、给 Webhook 加鉴权、只开放需要的工作流入口,并避免在日志里打印敏感字段。

还有一个很容易忽略的点:测试数据不要直接沿用真实订单、真实手机号、真实 access token。Webhook 调试阶段只需要确认字段结构和触发链路,示例数据用 order_ideventsource 这类脱敏字段就够了。等链路稳定后,再把业务节点接上真实系统。

如果团队里多人一起调试,建议把当前公网地址、Webhook Path、请求方法写在同一份联调说明里。地址变更后同步更新,不要让第三方平台、n8n 节点、文档里各放一份旧地址。Webhook 排错最怕信息不同步,路径少一个字符都能让请求进不到工作流。

9 总结

到这里,本地 n8n 已经跑在 Docker Compose 里,Webhook 节点也完成了从本地测试到公网回调的完整验证。以后遇到外部平台回调本地服务,不用再卡在 localhost 这一步,按“本地先通,再映射公网,再接第三方”的顺序排就行。

关键步骤可以记成三段:

  • 先用 Docker Compose 启动 n8n,并确认 http://localhost:5678 能打开。
  • Webhook 节点先用 /webhook-test/local-demo 配合 curl 本地调试,确认请求数据能进工作流。
  • 用 cpolar 映射 5678,把 HTTPS 根地址写入 WEBHOOK_URL,激活工作流后用 /webhook/local-demo 接正式回调。

如果只是临时联调,随机 HTTPS 地址已经够用;如果要接长期业务回调,就把地址固定下来,再把鉴权、签名校验和执行记录清理补上。自动化工作流最怕链路混在一起排错,把每一段都单独验证清楚,后面接 GitHub、飞书、企业微信或支付通知,都会顺很多。

更多推荐