tva
← 洞察

2025 年 n8n 自托管故障排除指南:解决执行数据大小与 webhook 问题(Traefik)

最后更新:2025 年 10 月 15 日

自托管 n8n 可实现不受限制的工作流执行、完全掌控数据,并且相比云端方案显著节省成本。但在实际使用中,自托管实例会遇到n8n Cloud 用户通常无需自行处理的问题,尤其是大数据处理,以及反向代理环境下的 webhook 配置。

2025 年 6 月,我们分别发布了两份故障排除指南,解决这两类问题。然而,对于使用 Traefik 反向代理的 n8n 生产部署,还缺少一份同时涵盖这两个常见问题的完整指南。

本指南整合了原来的两套修复方案,提供支持 WebSocket 的完整 Traefik 配置,涵盖 2025 年新增的任务运行器要求,并给出可立即部署、可用于生产环境的 docker-compose 文件。


目录

  1. 快速诊断:您遇到了哪类问题?
  2. 理解两类主要问题
  3. 修复 #1:执行数据过大错误
  4. 修复 #2:webhook URL 问题
  5. 使用 Traefik 的完整生产环境配置
  6. 2025 年要求:任务运行器
  7. 环境变量参考
  8. Docker Compose 示例
  9. 测试部署配置
  10. 常见问题排查

快速诊断:您遇到了哪类问题?

症状:“Existing execution data is too large”(现有执行数据过大)

出现此错误的场景:

  • 在开发工作流时点击“Execute Node”(执行节点)
  • 测试包含大型数据集或大量数据项的工作流
  • 使用部分执行模式(测试单个节点)
  • 处理涉及多个分支的复杂数据转换

所需方案:修复 #1:执行数据大小


症状:webhook 显示错误的 URL 或无法工作

出现此问题的场景:

  • webhook URL 中带有端口号(例如 :5678)
  • 外部服务(Slack、GitHub、Stripe)无法访问您的 webhook
  • webhook 在测试模式下正常,但在生产环境中失效
  • 使用了反向代理(Nginx、Traefik、Caddy)

所需方案:修复 #2:webhook URL 配置


症状:出现与任务运行器有关的弃用警告

日志中出现以下信息:

Running n8n without task runners is deprecated. Task runners will be
turned on by default in a future version.

所需方案:任务运行器配置


需求:一套完整、可用于生产环境的配置

所需方案:

  • 正确应用两项修复
  • 使用自动启用 HTTPS 的 Traefik 反向代理
  • 遵循生产环境最佳实践与安全要求
  • 设置资源限制并进行适当监控

跳转至:完整生产环境配置


理解两类主要问题

为什么 n8n Cloud 用户很少需要处理这些问题

在 n8n Cloud 上,n8n 会为您管理服务器配置,例如 webhook URL、二进制数据存储和更新。自托管时,这些配置需要由您负责。

根本原因

问题 #1:执行数据大小限制

发送到后端的请求载荷(包括部分执行数据)默认受 16 MiB 限制。处理大型数据集、包含大量分支的工作流或复杂转换时,这一限制会触发错误,导致开发过程中无法测试单个节点。修复方法很简单:设置环境变量 N8N_PAYLOAD_SIZE_MAX。

问题 #2:webhook URL 生成

n8n 会尝试自动检测公网 URL,但在反向代理后运行时,这种检测会失败。外部服务收到带有端口号或内部主机名的错误 webhook URL,导致集成悄然失效。修复方法:设置环境变量 WEBHOOK_URL。


修复 #1:执行数据过大错误

问题详解

只执行工作流的一部分时(在编辑器中点击“Execute Node”),n8n 需要加载先前的执行数据,为该节点提供上下文。默认情况下,n8n 将此请求限制为 16 MiB(N8N_PAYLOAD_SIZE_MAX=16,数值单位为 MiB),以防止资源较少的服务器出现内存问题。如果请求超过限制,n8n(或请求体上限更低的反向代理)会返回 HTTP 413,编辑器就会显示此错误。

错误信息

根据 n8n 官方文档:

Please execute the whole workflow, rather than just the node.
(Existing execution data is too large.)

在单个节点中处理数千个数据项、处理大型 JSON API 响应、使用 Code 节点转换大型数据集,或运行包含大量并行分支的工作流时,都可能出现此错误。

解决方案:N8N_PAYLOAD_SIZE_MAX

修复方法很简单,但需要先了解服务器的可用资源。

按服务器内存推荐的设置

服务器内存N8N_PAYLOAD_SIZE_MAX应设置的值(MiB)内存占比
2GB 或更低64MB64~3%
4GB128MB128~3%
8GB256MB256~3%
16GB+512MB512~3%

经验法则:设置值应低于可用内存的 20%,以保持系统在有负载时的稳定性。

通过 Docker Compose 配置

version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_PORT=5678

      # Payload size fix (256MB for 8GB+ RAM servers; value in MiB)
      - N8N_PAYLOAD_SIZE_MAX=256

      # Binary data optimization (highly recommended)
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
      - N8N_BINARY_DATA_TTL=1440  # 24 hours

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

    # Resource limits (adjust based on your server)
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 1G

volumes:
  n8n_data:

理解二进制数据模式

默认模式:内存存储(不推荐)

# This is the default - DON'T use in production
N8N_DEFAULT_BINARY_DATA_MODE=default

问题:将文件(图像、PDF 等)存储在内存中,浪费宝贵的内存资源,不适合生产工作负载,也限制了可处理的文件数量。

我们的测试结果显示:空闲时,默认模式使用约 315MB 内存,文件系统模式使用 211MB,即空闲内存使用量低约 100MB。

推荐模式:文件系统存储

N8N_DEFAULT_BINARY_DATA_MODE=filesystem
N8N_BINARY_DATA_TTL=1440  # Clean up after 24 hours (value in minutes)

优势:将文件存储在磁盘而非内存中,处理大文件时性能明显更好;该模式可用于生产环境,也是 n8n 推荐的方式。请注意,N8N_BINARY_DATA_TTL 自 n8n 1.9.0 起已无效:n8n 会在清理执行记录时删除二进制数据,因此磁盘使用量由执行记录清理设置控制。

注意:如果使用队列模式(基于 Redis 的分布式执行),n8n 在该模式下不支持文件系统模式。截至 2026 年 10 月,n8n 文档建议队列模式使用 database 模式。

实际效果

以下是我们在 2025 年 10 月使用 n8n 1.115.2 进行 Docker 测试的结果:

配置内存使用量差值
默认配置(未修复)315 MB基准值
应用载荷大小修复并启用文件系统模式211 MB-104 MB

关键发现:在我们的空闲状态测量中,调整请求载荷上限并启用文件系统二进制模式的配置比默认配置使用更少的内存。我们没有测量大请求载荷负载下的内存使用量,这种情况下的使用量取决于您的工作流。


修复 #2:webhook URL 问题

问题详解

n8n 在生成用于编辑器显示和向外部服务注册的 webhook URL 时,会尝试自动检测公网 URL。但在反向代理后运行时,这种自动检测会完全失效。

您会看到的错误 URL

http://n8n.yourdomain.com:5678/webhook/abc123

此 URL 的问题:

  1. 包含端口号(:5678)——外部服务通常无法访问非标准端口
  2. 协议错误(http 而非 https)——许多服务要求使用 HTTPS
  3. 内部主机名——可能使用了 Docker 容器名,而不是公网域名

外部服务为何会失败

GitHub、Slack、Stripe、Zoom、Google Sheets 等数百种服务会尝试向这些错误的 URL 发送 webhook,却在没有明显提示的情况下失败。集成已设置好,界面上看起来也正确,但通知始终无法送达。

解决方案:WEBHOOK_URL 环境变量

根据 n8n 官方文档:

“WEBHOOK_URL 环境变量用于手动设置 webhook URL,以便 n8n 在编辑器界面中显示该 URL,并向外部服务注册正确的 webhook URL。在反向代理后运行 n8n 时,设置此变量很重要。”

基本配置

environment:
  - WEBHOOK_URL=https://n8n.yourdomain.com
  - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
  - N8N_PROTOCOL=https
  - N8N_HOST=n8n.yourdomain.com
  - N8N_TRUST_PROXY_HEADER=true
  - N8N_PROXY_HOPS=1

各变量的作用

WEBHOOK_URL(最重要)

  • 所有 webhook 端点的公网 URL
  • 向外部服务注册 webhook 时使用
  • 必须与 Traefik 或其他反向代理的配置完全一致
  • 版本说明:原名为 WEBHOOK_TUNNEL_URL,在 v0.227.0 中更名,旧名称在 n8n 1.0 中移除

N8N_EDITOR_BASE_URL

  • 访问 n8n 网页界面的 URL
  • 通常与 WEBHOOK_URL 相同
  • 显示在浏览器地址栏和邀请邮件中

N8N_PROTOCOL

  • 设为 https,用于生产环境(启用 SSL/TLS)
  • 设为 http,仅用于本地测试
  • 必须与反向代理终止连接时使用的协议一致

N8N_HOST

  • 只填写公网域名
  • 不要包含协议(https://)或端口号
  • 例如:n8n.yourdomain.com,而非 https://n8n.yourdomain.com:443

N8N_TRUST_PROXY_HEADER

  • 不是 n8n 文档中列出的变量:它未出现在 n8n 环境变量参考文档中,因此设置它没有文档说明的效果
  • 是否信任代理请求头(用于获取客户端真实 IP 地址)由 N8N_PROXY_HOPS 控制
  • 您可以在本指南的示例中省略它

N8N_PROXY_HOPS

  • 设为 1,用于经过一层反向代理的情况
  • 设为 2,用于经过两层代理的情况(较少见)
  • 告诉 n8n 应信任多少层代理

测试 webhook URL

修复前

在 n8n 界面中创建一个 Webhook 节点,检查显示的 URL:

http://n8n.example.com:5678/webhook/abc123  ❌ Wrong

修复后

同一个 Webhook 节点现在显示:

https://n8n.example.com/webhook/abc123  ✅ Correct

关键区别:外部服务现在能够访问此 URL,因为它使用标准 HTTPS 端口 443(由反向代理处理),而不是内部端口 5678。


使用 Traefik 的完整生产环境配置

为什么选择 Traefik?

Traefik 是一款非常适合 Docker 部署的现代反向代理。它通过 Let’s Encrypt 自动启用 HTTPS,无需手动管理证书;通过 Docker 标签自动发现容器;原生支持 n8n 编辑器实时连接所用的 WebSocket;仅使用 Docker 标签即可配置,无需复杂的配置文件;还内置仪表盘,可实时监控路由和证书。

架构概览

Internet
  ↓
[Traefik Reverse Proxy]
  ↓ HTTPS (Let's Encrypt)
  ↓ WebSocket Support
[n8n 容器]
  ↓ 内部网络
[PostgreSQL 数据库]

WebSocket 支持

Traefik 原生支持代理 WebSocket 连接,包括 n8n 编辑器使用的实时连接,因此无需额外的中间件。webhook 是普通的 HTTPS 请求,不依赖 WebSocket。下方的生产示例包含可选的 WebSocket 请求头标签,您可以省略这些标签。

完整的生产环境 Docker Compose 配置

此配置整合了两项修复,包含正确支持 WebSocket 的 Traefik 配置,并遵循生产环境最佳实践:

version: '3.8'

networks:
  traefik-net:
    external: true
  n8n-internal:
    internal: true

services:
  # PostgreSQL Database
  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    networks:
      - n8n-internal
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 512M

  # n8n Application
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - traefik-net
      - n8n-internal

    # Traefik Configuration Labels
    labels:
      # Enable Traefik for this container
      - "traefik.enable=true"
      - "traefik.docker.network=traefik-net"

      # Router configuration
      - "traefik.http.routers.n8n.rule=Host(`${N8N_DOMAIN}`)"
      - "traefik.http.routers.n8n.entrypoints=websecure"
      - "traefik.http.routers.n8n.tls.certresolver=letsencrypt"

      # Service configuration
      - "traefik.http.services.n8n.loadbalancer.server.port=5678"

      # Middleware: Request size limit in bytes (256MB, matches N8N_PAYLOAD_SIZE_MAX)
      - "traefik.http.middlewares.n8n-buffering.buffering.maxRequestBodyBytes=268435456"

      # Middleware: WebSocket headers (optional; Traefik proxies WebSockets natively)
      - "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Upgrade=websocket"
      - "traefik.http.middlewares.n8n-websocket.headers.customrequestheaders.Connection=Upgrade"

      # Middleware: Security headers
      - "traefik.http.middlewares.n8n-security.headers.customResponseHeaders.X-Robots-Tag=noindex,nofollow"
      - "traefik.http.middlewares.n8n-security.headers.sslProxyHeaders.X-Forwarded-Proto=https"

      # Apply ALL middlewares
      - "traefik.http.routers.n8n.middlewares=n8n-buffering,n8n-websocket,n8n-security"

    environment:
      # Database Configuration
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}

      # FIX #2: Webhook URL Configuration
      - WEBHOOK_URL=https://${N8N_DOMAIN}
      - N8N_EDITOR_BASE_URL=https://${N8N_DOMAIN}
      - N8N_PROTOCOL=https
      - N8N_HOST=${N8N_DOMAIN}
      - N8N_PORT=5678
      - N8N_TRUST_PROXY_HEADER=true
      - N8N_PROXY_HOPS=1

      # FIX #1: Payload Size Configuration
      - N8N_PAYLOAD_SIZE_MAX=256  # 256 MiB

      # Binary Data Management
      - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
      - N8N_BINARY_DATA_TTL=1440  # 24 hours

      # 2025 Requirement: Task Runners
      - N8N_RUNNERS_ENABLED=true
      - N8N_RUNNERS_MODE=internal
      - N8N_RUNNERS_MAX_CONCURRENCY=5

      # Production Optimizations
      - NODE_ENV=production
      - EXECUTIONS_DATA_MAX_AGE=168  # 7 days
      - EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
      - N8N_LOG_LEVEL=info
      - N8N_LOG_OUTPUT=console

      # Timezone (adjust to your location)
      - GENERIC_TIMEZONE=America/New_York
      - TZ=America/New_York

      # Security
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

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

    # Resource Limits (8GB+ RAM server)
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '2.0'
        reservations:
          memory: 1G
          cpus: '1.0'

    # Health Check
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5678/healthz"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  n8n_data:
  postgres_data:

Traefik 配置

如果您尚未运行 Traefik,以下是完整的配置步骤:

步骤 1:创建 Traefik 网络

docker network create traefik-net

步骤 2:创建 Traefik 配置文件

创建 traefik/traefik.yml:

api:
  dashboard: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-net

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]  # CHANGE THIS
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

log:
  level: INFO

accessLog: {}

步骤 3:创建 Traefik Docker Compose 文件

创建 traefik/docker-compose.yml:

version: '3.8'

networks:
  traefik-net:
    external: true

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - traefik-net
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # Dashboard (secure this in production!)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yml:/traefik.yml:ro
      - ./letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"

步骤 4:创建环境变量文件

创建 .env,放在 n8n 目录中:

# Domain Configuration
N8N_DOMAIN=n8n.yourdomain.com

# Database Password (generate secure password)
DB_PASSWORD=your_secure_db_password_here

# n8n Encryption Key (generate random string)
N8N_ENCRYPTION_KEY=your_encryption_key_here

生成安全的密码和密钥:

# For DB_PASSWORD
openssl rand -base64 32

# For N8N_ENCRYPTION_KEY
openssl rand -hex 32

步骤 5:启动所有服务

# Start Traefik first
cd traefik
docker compose up -d

# Wait a few seconds, then start n8n
cd ../n8n
docker compose up -d

# Watch logs to verify startup
docker compose logs -f n8n

验证部署配置

检查 Traefik 仪表盘

访问 http://your-server-ip:8080。仅当您同时在 traefik.yml 中设置 api.insecure: true 时,此方式才有效(仅用于测试);否则,请在专用域名上为仪表盘(api@internal)配置路由器。

应显示:

  • ✅ n8n 路由器已启用,状态为绿色
  • ✅ 已获取 Let’s Encrypt 证书
  • ✅ 服务标记为健康状态

检查 n8n 访问

访问 https://n8n.yourdomain.com

应显示:

  • ✅ HTTPS 正常工作,使用有效的 Let’s Encrypt 证书
  • ✅ 浏览器未出现安全警告
  • ✅ n8n 登录或设置页面正常显示

检查 webhook URL

  1. 登录 n8n
  2. 创建新工作流
  3. 添加 Webhook 节点
  4. 检查显示的“Production URL”(生产 URL)

预期结果:

https://n8n.yourdomain.com/webhook/abc123

不应显示以下结果(表示配置错误):

http://n8n.yourdomain.com:5678/webhook/abc123  ❌

2025 年要求:任务运行器

什么是任务运行器?

任务运行器在隔离进程中执行 Code 节点定义的代码,而不是在 n8n 主进程中执行。沙盒环境提高了安全性,代码错误不会使主进程崩溃,从而改善稳定性;同时,后续 n8n 版本将要求使用任务运行器,提前配置有助于保持兼容性。

为什么现在需要配置

摘自 n8n 官方文档:

“不使用任务运行器运行 n8n 的方式已被弃用。未来版本将默认启用任务运行器。建议用户现在设置 N8N_RUNNERS_ENABLED=true,以避免将来可能出现的问题。”

以下摘自我们的测试日志(2025 年 10 月):

There are deprecations related to your environment variables:
 - N8N_RUNNERS_ENABLED -> Running n8n without task runners is deprecated.

配置

内部模式(单服务器推荐)

environment:
  - N8N_RUNNERS_ENABLED=true
  - N8N_RUNNERS_MODE=internal
  - N8N_RUNNERS_MAX_CONCURRENCY=5

n8n 将任务运行器作为子进程启动。这是最简单的配置,无需额外基础设施,适合大多数自托管部署,性能开销也很小。 截至 2026 年 10 月,n8n 文档将内部模式描述为在设计上不安全,并从 n8n 3.0 起将其弃用。

外部模式(适用于分布式部署)

environment:
  - N8N_RUNNERS_ENABLED=true
  - N8N_RUNNERS_MODE=external
  - N8N_RUNNERS_AUTH_TOKEN=your_secure_token

独立的任务运行器容器可为高处理量工作流提供更好的资源隔离,并支持跨多台服务器横向扩展,并以 n8nio/runners 镜像的边车容器运行,其版本必须与 n8n 镜像版本一致。使用 Docker Compose 配置即可,无需 Docker Swarm 或 Kubernetes。

验证任务运行器

检查进程列表

docker exec n8n ps aux

未启用任务运行器(3 个进程):

PID   USER     TIME  COMMAND
    1 node      0:00 tini -- /docker-entrypoint.sh
    7 node      0:12 node /usr/local/bin/n8n

启用任务运行器(4 个进程):

PID   USER     TIME  COMMAND
    1 node      0:00 tini -- /docker-entrypoint.sh
    7 node      0:16 node /usr/local/bin/n8n
   18 node      0:10 node [...]/task-runner/dist/start.js

验证依据:进程列表中可见 PID 为 18 的任务运行器进程。

检查日志

docker logs n8n | grep -i runner

应看到:

n8n Task Broker ready on 127.0.0.1, port 5679
Registered runner "JS Task Runner" (zCWpF0Eb_LJsqWYvLm5t1)

对资源使用量的影响

以下是我们的 Docker 测试结果(2025 年 10 月,n8n 1.115.2):

配置内存CPU进程数
未启用任务运行器214 MB0.14%3
启用任务运行器289 MB0.29%4
差值+75 MB+0.15%+1

资源开销很小。安全性、稳定性和对未来版本的兼容性带来的收益,远大于这点资源成本。


环境变量参考

完整变量列表

变量类型默认值用途优先级
关键变量
WEBHOOK_URL字符串–公网 webhook URL必需,使用反向代理时
N8N_PAYLOAD_SIZE_MAX数值16 (MiB)请求载荷大小上限,单位为 MiB,包括部分执行数据必需,处理大量数据时
N8N_RUNNERS_ENABLED布尔值false启用任务运行器1.x 版本推荐(n8n 2.0 起无需设置)
N8N_TRUST_PROXY_HEADER––未列入 n8n 文档中的变量无需设置;使用 N8N_PROXY_HOPS
webhook 配置
N8N_EDITOR_BASE_URL字符串–编辑器界面 URL推荐
N8N_PROTOCOL字符串http协议(http/https)生产环境
N8N_HOST字符串localhost公网主机名生产环境
N8N_PORT数值5678内部端口可选
N8N_PROXY_HOPS数值0反向代理层数使用代理时设为 1
性能
N8N_DEFAULT_BINARY_DATA_MODE字符串default二进制数据存储模式推荐
N8N_BINARY_DATA_TTL––自 n8n 1.9.0 起无效(二进制数据随执行记录一起清理)可安全移除
任务运行器
N8N_RUNNERS_MODE字符串internal任务运行器模式启用任务运行器时
N8N_RUNNERS_MAX_CONCURRENCY数值10每个运行器的最大并发任务数可选

按场景提供的预设配置

场景 A:开发(本地机器)

environment:
  - N8N_PORT=5678

适用场景:本地测试,不使用反向代理,无生产环境要求

场景 B:在反向代理后运行(不处理大量数据)

environment:
  - N8N_PORT=5678
  - WEBHOOK_URL=https://n8n.yourdomain.com
  - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
  - N8N_PROTOCOL=https
  - N8N_HOST=n8n.yourdomain.com
  - N8N_TRUST_PROXY_HEADER=true
  - N8N_PROXY_HOPS=1
  - N8N_RUNNERS_ENABLED=true

适用场景:对外开放的 n8n 实例,需要 webhook,工作流规模较小

场景 C:完整生产环境配置

environment:
  # Database
  - DB_TYPE=postgresdb
  - DB_POSTGRESDB_HOST=postgres
  - DB_POSTGRESDB_PORT=5432
  - DB_POSTGRESDB_DATABASE=n8n
  - DB_POSTGRESDB_USER=n8n
  - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}

  # Webhooks
  - WEBHOOK_URL=https://n8n.yourdomain.com
  - N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
  - N8N_PROTOCOL=https
  - N8N_HOST=n8n.yourdomain.com
  - N8N_PORT=5678
  - N8N_TRUST_PROXY_HEADER=true
  - N8N_PROXY_HOPS=1

  # Performance
  - N8N_PAYLOAD_SIZE_MAX=256  # 256 MiB
  - N8N_DEFAULT_BINARY_DATA_MODE=filesystem
  - N8N_BINARY_DATA_TTL=1440

  # Task Runners
  - N8N_RUNNERS_ENABLED=true
  - N8N_RUNNERS_MODE=internal
  - N8N_RUNNERS_MAX_CONCURRENCY=5

  # Production
  - NODE_ENV=production
  - EXECUTIONS_DATA_MAX_AGE=168  # 7 days
  - EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
  - N8N_LOG_LEVEL=info

  # Security
  - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}

适用场景:启用所有功能、运行大型工作流并允许公网访问的生产部署


Docker Compose 示例

我们测试环境中的四种场景配置均可使用。这些配置已于 2025 年 10 月使用 n8n 1.115.2 验证。 示例使用 latest 镜像标签;要复现已测试的版本,请固定为 n8nio/n8n:1.115.2。

资源使用量对比(我们的测试结果)

场景内存CPU进程数说明
默认配置315 MB0.00%3未应用修复,作为基准
载荷大小修复211 MB0.00%3载荷大小修复与文件系统模式
webhook 修复215 MB0.14%3仅配置 webhook
生产环境289 MB0.29%4全部修复与任务运行器

关键发现:在我们的测试中,空闲时应用全部修复的生产配置比默认配置使用更少的内存。这些是空闲状态下的测量值,并非大请求载荷负载下的结果。


测试部署配置

部署前检查清单

1. DNS 配置

# Verify DNS points to your server
nslookup n8n.yourdomain.com

# Should return your server's public IP

2. 端口可用性

# Check if required ports are free
sudo netstat -tlnp | grep -E '(80|443|5678)'

# Should show nothing or only Traefik on 80/443

3. Docker 安装

# Verify Docker
docker --version

# Verify Docker Compose
docker compose version

4. 环境变量

# Verify .env file exists
cat .env

# Should show N8N_DOMAIN, DB_PASSWORD, N8N_ENCRYPTION_KEY

部署步骤

# Step 1: Create Traefik network
docker network create traefik-net

# Step 2: Start Traefik
cd traefik
docker compose up -d

# Step 3: Wait for Traefik to be ready
sleep 10

# Step 4: Start n8n
cd ../n8n
docker compose up -d

# Step 5: Watch logs for any errors
docker compose logs -f n8n

部署后测试

测试 1:HTTPS 访问

curl -I https://n8n.yourdomain.com

预期结果: HTTP/2 200(或 HTTP/1.1 200)

测试 2:HTTP 到 HTTPS 的重定向

curl -I http://n8n.yourdomain.com

预期结果: HTTP/1.1 308 Permanent Redirect,并带有 Location: https://n8n.yourdomain.com

测试 3:容器健康状态

docker ps

预期结果:容器 n8n 和 n8n-postgres 均显示 (healthy) 状态

测试 4:webhook URL 格式

  1. 登录 n8n 网页界面
  2. 创建新工作流
  3. 添加 Webhook 节点
  4. 检查显示的“Production URL”(生产 URL)

预期格式:

https://n8n.yourdomain.com/webhook/abc123

不应显示以下结果(配置错误):

http://n8n.yourdomain.com:5678/webhook/abc123  ❌

测试 5:任务运行器是否启用

docker logs n8n | grep -i runner

预期输出:

Registered runner "JS Task Runner"

测试 6:环境变量是否生效

docker exec n8n env | grep N8N_PAYLOAD_SIZE_MAX

预期结果: N8N_PAYLOAD_SIZE_MAX=256


常见问题排查

问题:HTTPS 无法工作

症状:浏览器显示“Not Secure”(不安全)警告或证书错误,无法通过 HTTPS 访问

诊断:

# Check Traefik logs for errors
docker logs traefik | grep -i error

# Check certificate file exists
ls -la traefik/letsencrypt/acme.json

# Verify DNS resolution
nslookup n8n.yourdomain.com

解决方案:

  1. DNS 未指向服务器:更新 DNS A 记录,使其指向服务器的公网 IP;等待 DNS 更新生效(最多 24 小时,通常要快得多);从其他网络测试:dig n8n.yourdomain.com +short
  2. 端口 80 被阻止:Let’s Encrypt 需要通过端口 80 完成 HTTP 验证。检查防火墙:sudo ufw status。若端口被阻止,请放行:sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
  3. Traefik 配置中的邮箱无效:编辑 traefik/traefik.yml,将 certificatesResolvers.letsencrypt.acme.email 更新为有效的邮箱地址,再重启 Traefik:docker compose restart

问题:webhook 返回 404

症状:外部服务报告 webhook 失败;webhook URL 看起来正确却无法使用;测试模式正常,但生产模式失败

诊断:

# Test webhook directly
curl -v https://n8n.yourdomain.com/webhook/test

# Check Traefik routing logs
docker logs traefik | grep webhook

# Verify n8n sees requests
docker logs n8n | grep webhook

解决方案:

  1. WEBHOOK_URL 设置不正确:检查环境变量:docker exec n8n env | grep WEBHOOK_URL。它应与您的域名完全一致:WEBHOOK_URL=https://n8n.yourdomain.com
  2. 网络配置错误:确认 n8n 已连接到 traefik-net:docker inspect n8n | grep -A 5 Networks。输出中应显示“traefik-net”

问题:仍然出现“Execution Data Too Large”(执行数据过大)错误

症状:设置 N8N_PAYLOAD_SIZE_MAX 后仍出现错误,大型工作流在点击“Execute Node”时失败

诊断:

# Verify variable is set
docker exec n8n env | grep PAYLOAD

# Should show N8N_PAYLOAD_SIZE_MAX=256

解决方案:

  1. 变量未生效(容器未重新创建):重新创建容器以应用更改:docker compose up -d n8n(docker compose restart 不会应用已修改的环境变量值)。随后验证:docker exec n8n env | grep PAYLOAD
  2. 工作流需要更高的限制值:对于配备 16GB+ 内存的服务器,将限制提高至 512MB:N8N_PAYLOAD_SIZE_MAX=512
  3. Traefik 请求大小限制过低:同时提高 Traefik 的限制(单位为字节),使其匹配:"traefik.http.middlewares.n8n-buffering.buffering.maxRequestBodyBytes=536870912"

问题:内存使用量过高

症状:容器在空闲时使用 >1.5GB 内存,内存使用量随时间增长,出现内存不足错误

诊断:

# Monitor memory
docker stats n8n

# Check binary data mode
docker exec n8n env | grep BINARY_DATA_MODE

解决方案:

  1. 未使用文件系统模式:添加以下环境变量:N8N_DEFAULT_BINARY_DATA_MODE=filesystem。效果:在我们的测试中,空闲内存使用量低约 100MB
  2. 旧执行记录不断积累:缩短保留期限:EXECUTIONS_DATA_MAX_AGE=168(从 14 天缩短为 7 天),并设置 EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
  3. 容器资源限制过低:如果服务器资源允许,可提高限制。在 deploy 的资源配置部分,将内存限制从 2G 改为 4G

结论

已解决的问题

本完整指南解决了 n8n 自托管中的两类最常见问题:

  1. ✅ 执行数据过大错误——通过设置 N8N_PAYLOAD_SIZE_MAX 并启用文件系统二进制模式修复
  2. ✅ webhook URL 问题——通过设置 WEBHOOK_URL 并正确配置反向代理修复

还补充了以下关键内容:

  1. ✅ 完整的 Traefik 配置——支持 WebSocket、可用于生产环境的配置
  2. ✅ 任务运行器配置——2025 年要求,为未来版本保持兼容性
  3. ✅ 生产环境最佳实践——资源限制、健康检查、安全响应头和监控
  4. ✅ 经过验证的配置——所有 docker-compose 文件均于 2025 年 10 月使用 n8n 1.115.2 测试

关键要点

快速修复:

  • 设置 N8N_PAYLOAD_SIZE_MAX=256,解决执行数据问题(8GB+ 内存采用 256MB)
  • 设置 WEBHOOK_URL=https://your-domain.com,解决 webhook 问题
  • 设置 N8N_RUNNERS_ENABLED=true,消除弃用警告
  • 使用 N8N_DEFAULT_BINARY_DATA_MODE=filesystem(在我们的测试中,空闲内存使用量低约 100MB)

生产部署:

  • 使用我们提供的完整 docker-compose.yml,其中包含 Traefik 配置
  • 无需 WebSocket 中间件——Traefik 原生支持代理 WebSocket,而 webhook 是普通的 HTTPS 请求
  • 使用 PostgreSQL,提高有负载时的性能
  • 根据服务器容量设置合适的资源限制
  • 配置健康检查,让监控系统和依赖服务能够检测故障(单独使用 Docker 只会将容器标记为不健康,不会将其重启)

Traefik 用户须知(关键):

  • Traefik 无需额外的中间件即可处理 WebSocket;webhook 需要正确的路由器和 WEBHOOK_URL
  • 将请求体大小限制设为等于或大于载荷大小
  • 配置安全相关头部(X-Robots-Tag、X-Forwarded-Proto)
  • 启动 Traefik 前,确保 DNS 指向您的服务器(Let’s Encrypt 的要求)

相比 2025 年 6 月文章新增的内容

功能2025 年 6 月文章本指南
执行数据修复✅ 详细介绍✅ 包含修复与资源测量结果
webhook 修复✅ 详细介绍✅ 包含修复与 Traefik 集成
Traefik 配置❌ 未涉及✅ 完整配置
WebSocket 支持❌ 未涉及✅ 重点强调
任务运行器❌ 未涉及✅ 2025 年要求
整合的 docker-compose 配置❌ 分别提供✅ 可用于生产环境
资源测量❌ 理论分析✅ 实际测试数据
环境变量✅ 已涉及✅ 完整参考

测试与验证

我们的测试环境(2025 年 10 月):

  • ✅ n8n 版本 1.115.2
  • ✅ Docker 容器运行 2+ 小时
  • ✅ 在运行中的容器内验证了所有环境变量
  • ✅ 使用以下命令测量资源使用量:docker stats
  • ✅ 在进程列表中确认了任务运行器进程
  • ✅ HTTP 端点经测试可访问
  • ✅ 已验证配置可正常工作

后续步骤

  1. 选择适用场景:
    • 开发:最小配置
    • 反向代理后运行:webhook 修复与任务运行器
    • 生产环境:包含 Traefik 的完整配置(推荐)
  2. 部署:
    • 复制适用的 docker-compose.yml
    • 创建 .env 文件,填写域名和安全的密码
    • 先启动 Traefik,再启动 n8n
    • 运行部署后测试
  3. 验证:
    • 验证 HTTPS 正常工作且证书有效
    • 检查 webhook URL 格式是否正确
    • 使用大型数据集测试(如有需要)
    • 确认任务运行器已注册
  4. 监控:
    • 使用以下命令监控资源使用量:docker stats
    • 配置健康检查告警(外部监控)
    • 配置日志轮转,防止磁盘写满
    • 安排定期备份数据卷

相关资源

2025 年 6 月文章:

n8n 官方文档:

遇到疑问或问题?

如果遇到本指南未涵盖的问题:

  1. 查阅我们的2025 年 6 月详细故障排除文章,获取更多指导
  2. 查阅 n8n 官方文档,了解最新功能
  3. 在 n8n 社区论坛中搜索类似问题
  4. 查看上方的常见问题排查章节
  5. 联系 tva,获取专业实施支持

可复现的测试

本指南中的所有配置均可在您自己的环境中复现。Docker Compose 文件可用于生产环境,环境变量已有说明并经过验证,还提供了用于验证的测试命令和明确的预期输出。您可以自行部署这些配置并运行所提供的测试,验证本指南中的每一项结论。

需要实施支持?

如果您希望由 tva 部署 n8n,或需要生产环境配置支持,请联系我们。我们为需要可靠、可用于生产环境的 n8n 基础设施的组织实施这些配置。


发布日期:2025 年 10 月 15 日
测试版本:n8n v1.115.2、Docker Compose v3.8、Traefik v2.10
服务器要求:生产环境建议配备 4GB+ 内存、2+ CPU 核心
依据:n8n 官方文档、经过验证的 Docker 测试和社区最佳实践

延伸阅读