Tropic Host

n8n:它是什么,以及如何通过 Docker Compose 安装到 VPS

阅读约需 12 分钟
Tropic
n8n:它是什么,以及如何通过 Docker Compose 安装到 VPS

VPS 上的 n8n:摆脱手工重复工作的自有自动化平台

网站收到一条申请。n8n 检查数据、查找重复记录、创建商机、借助 AI 准备回复草稿,并在 Telegram 中通知经理。只有在需要做决定时才由人介入,而不是让人负责在不同标签页之间搬运数据。

下面我们将介绍 n8n 的工作原理,以及如何通过 Docker Compose 在 VPS 上安装带有 PostgreSQL、HTTPS 和隔离代码执行的 n8n。

七步部署 n8n

最简启动方案:

  1. 创建一台 VPS,并将一个子域名指向它,例如 n8n.example.com
  2. 安装 Docker 和 Docker Compose。
  3. 启动带有 PostgreSQL、外部任务运行器和 Caddy 的 n8n。
  4. 通过 HTTPS 打开界面并创建所有者账户。
  5. 连接 Telegram、CRM、邮箱或任意外部 API。
  6. 配置错误处理和执行记录的保留期限。
  7. 自动备份数据库、数据和加密密钥。

对于小型生产环境,从 2 vCPU 和 4 GB RAM 起步比较合理。测试时 2 GB 往往也够用,但 PostgreSQL、Docker 和并行进程会很快消耗掉剩余资源。

n8n 是什么,它如何工作

n8n 是一个工作流自动化平台。一个流程由多个节点组成:第一个节点启动流程,后续节点获取并转换数据,最后一个节点执行操作。

一个简单的工作流如下:

Webhook → 数据检查 → CRM → Telegram → 向网站返回响应

流程可以由 webhook、定时任务、邮件、消息或外部服务事件触发。节点之间可以使用条件、循环、过滤、等待和错误处理。

n8n 的优势之一,是自动化不受现成集成的限制。任何提供 API 的服务都可以通过 HTTP Request 调用,非标准逻辑则可以在 Code node 中使用 JavaScript 或 Python 编写。因此,n8n 介于简单的无代码构建器和自行编写的服务端代码之间。

它为什么不只是转发数据

当一个流程跨越多个系统并且需要做出判断时,n8n 尤其有用:

表单 → 检查 → 查找重复项 → AI 评估 → 经理确认 → CRM

人只需要保留在关键审核点。例如,AI 准备回复,但只有员工批准后,消息才会发送给客户。

常见场景:

  • 销售与支持: 收集申请、分配潜在客户并创建商机;
  • 内容与 AI: 生成草稿、对咨询分类,并在审核后发布;
  • DevOps: 故障通知、来自 Git 的 webhook 和 API 检查;
  • 内部运营: 同步表格、邮箱、日历和企业系统。

自托管安装让你掌控流程和数据库,但不会把外部服务变成本地服务。发送到 Telegram、CRM 或云端 AI 模型的数据仍会离开 VPS。

n8n Cloud 还是自有服务器

参数n8n CloudVPS 上的 n8n
启动无需配置服务器需要域名、Docker 和 HTTPS
更新由 n8n 完成由所有者完成
数据库和文件位于服务商基础设施中位于所选服务器上
扩展按云端套餐条件进行自行配置
责任管理工作更少备份、安全和监控由所有者负责
适合人群不想处理 DevOps、需要快速开始需要控制权、定制和持续运行的流程

Community Edition 可以免费自行托管,并用于个人及企业内部流程。不过,n8n 并非采用传统的开源许可证,而是采用 fair-code 模式的 Sustainable Use License。该许可证允许内部使用和修改,但不允许简单地部署 n8n、换上自己的标识,再将访问权限作为独立 SaaS 出售。对于这类产品,需要单独核对许可条款。

n8n 对服务器的要求

负载取决于数据量、并发程度和操作类型。文件、长列表、Code node 和 AI 工作流所需的内存,会高于在 API 之间传递少量 JSON 的流程。

场景起步配置
测试和个人文本工作流1 vCPU、2 GB RAM、20 GB NVMe
小型生产环境2 vCPU、4 GB RAM、25–40 GB NVMe
并行流程、AI 或文件处理4 vCPU、8 GB RAM 或更多
queue mode 下的多个 worker 进程按执行数量估算

SQLite 适合入门和小型单实例。生产环境更适合 PostgreSQL:备份更方便,之后切换到 queue mode 也更容易。

如何在 VPS 上安装 n8n

本示例使用 Ubuntu 24.04、PostgreSQL、Caddy 和外部任务运行器。请将 n8n.example.com 和时区替换为你自己的值。

1. 配置 DNS 并准备服务器

创建一条指向 VPS IPv4 地址的 DNS A 记录,然后通过 SSH 连接:

ssh root@SERVER_IP
apt update && apt upgrade -y
apt install -y ca-certificates curl ufw openssl

从官方仓库安装 Docker Engine 和 Compose 插件:

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

cat > /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

apt update
apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
docker compose version

只开放 SSH、HTTP 和 HTTPS:

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

在确认新的 SSH 连接可以正常建立之前,不要关闭当前会话。

2. 创建环境变量

准备目录:

mkdir -p /opt/n8n
cd /opt/n8n

创建 .env。下面的命令会立即为 PostgreSQL、n8n 加密和任务运行器分别生成不同的随机密钥:

cat > .env <<EOF
N8N_VERSION=stable
N8N_HOST=n8n.example.com
GENERIC_TIMEZONE=Europe/Berlin

POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=$(openssl rand -hex 32)

N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
RUNNERS_AUTH_TOKEN=$(openssl rand -hex 32)
EOF

chmod 600 .env

首次启动时使用 stable 标签比较方便。确认安装正常后,最好固定一个具体的 n8n 版本,避免下一次镜像更新在意料之外发生。

绝不能丢失 N8N_ENCRYPTION_KEY。n8n 使用这个密钥加密已保存的密码、令牌和其他凭据。如果只恢复 PostgreSQL 而没有恢复密钥,记录仍会保留在数据库中,但 n8n 无法读取它们。

3. 创建 Docker Compose 配置

创建文件 compose.yaml

services:
  postgres:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      PGDATA: /var/lib/postgresql/data
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
    restart: unless-stopped
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: "5432"
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}

      N8N_HOST: ${N8N_HOST}
      N8N_PORT: "5678"
      N8N_PROTOCOL: https
      N8N_EDITOR_BASE_URL: https://${N8N_HOST}
      N8N_WEBHOOK_URL: https://${N8N_HOST}/
      N8N_PROXY_HOPS: "1"
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      TZ: ${GENERIC_TIMEZONE}

      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
      N8N_BLOCK_ENV_ACCESS_IN_NODE: "true"

      N8N_RUNNERS_MODE: external
      N8N_RUNNERS_AUTH_TOKEN: ${RUNNERS_AUTH_TOKEN}
      N8N_RUNNERS_BROKER_LISTEN_ADDRESS: 0.0.0.0

      EXECUTIONS_DATA_PRUNE: "true"
      EXECUTIONS_DATA_MAX_AGE: "168"
      EXECUTIONS_DATA_PRUNE_MAX_COUNT: "10000"
    volumes:
      - n8n_data:/home/node/.n8n
    expose:
      - "5678"
    depends_on:
      postgres:
        condition: service_healthy

  n8n-runner:
    image: n8nio/runners:${N8N_VERSION}
    restart: unless-stopped
    environment:
      N8N_RUNNERS_AUTH_TOKEN: ${RUNNERS_AUTH_TOKEN}
      N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
    depends_on:
      - n8n

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    environment:
      N8N_HOST: ${N8N_HOST}
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - n8n

volumes:
  postgres_data:
    name: n8n_postgres_data
  n8n_data:
    name: n8n_data
  caddy_data:
    name: n8n_caddy_data
  caddy_config:
    name: n8n_caddy_config

外部任务运行器会在 n8n 主进程之外执行代码。这比内部模式更安全,也能避免 Code node 中的错误轻易影响编辑器和 webhook 处理。

4. 启用 HTTPS

创建 Caddyfile

{$N8N_HOST} {
    reverse_proxy n8n:5678
}

如果 DNS 已经指向 VPS,并且 80 和 443 端口可以访问,Caddy 会自动获取 TLS 证书。内部端口 5678 不会暴露到互联网:外部只能访问 80 和 443,Caddy 则通过 Docker 网络连接 n8n。

需要设置 N8N_WEBHOOK_URLN8N_PROXY_HOPS,这样编辑器才能生成正确的公开 webhook 地址,并信任来自一个反向代理的请求头。

5. 启动 n8n

检查最终配置并启动容器:

docker compose config
docker compose up -d
docker compose ps
docker compose logs --tail=100 n8n caddy

打开:

https://n8n.example.com

创建所有者账户。不要把它的密码交给同事:团队协作时应使用独立账户,并且只授予必要权限。

第一个实用工作流

一个不错的测试,是处理来自网站的申请:

  1. 添加一个使用 POST 方法的 Webhook 节点。
  2. 通过 Edit Fields 只保留姓名、电子邮箱和来源。
  3. 使用 If 节点拒绝缺少必填数据的申请。
  4. 在 CRM 中创建商机,或通过 HTTP Request 发送请求。
  5. 添加 Telegram 通知。
  6. 使用 Respond to Webhook 节点结束流程。
  7. 测试完成后启用工作流,并将测试 webhook 替换为生产 URL。

这个示例可以一次性检查域名、HTTPS、入站请求、凭据和外部集成是否正常。之后还应添加一个独立的 Error Workflow,在主流程失败时发送通知。

安装后的 n8n 安全设置

安装完成并不代表 n8n 已经可靠。启动后请检查:

  • 编辑器只能通过 HTTPS 访问;
  • .env 权限为 600,并且不会提交到 Git;
  • 外部 API 密钥只拥有最低必要权限;
  • webhook 会验证来源签名或密钥;
  • 执行历史会自动清理;
  • 关键工作流的错误会发送给管理员。

Community nodes 以软件包形式安装,可能获得对工作流数据和服务器的访问权限。不要在未经审核的情况下添加未知节点。如果不需要它们,请通过 N8N_COMMUNITY_PACKAGES_ENABLED=false 禁用。

运行内置审计:

docker compose exec n8n n8n audit

它可以帮助发现未受保护的 webhook、高风险节点和凭据问题,但不能替代人工检查。

执行历史与个人数据

n8n 会保存输入和输出数据以便调试。电子邮件、电话号码、文档和 API 响应也可能随之保留在数据库中。

在上述配置中,执行记录会在七天后删除,并且总数限制为 10,000 条。对于敏感流程,应根据数据保留政策选择期限,并在工作流结束前删除不必要的字段。

备份与更新

恢复时需要 PostgreSQL 转储、n8n_data 卷、配置文件,以及包含 N8N_ENCRYPTION_KEY.env。复制前,请停止处理进程,但保持 PostgreSQL 运行。这会让工作流短暂中断:

cd /opt/n8n
mkdir -p backup
docker compose stop n8n n8n-runner

docker compose exec -T postgres sh -c \
  'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' \
  | gzip > "backup/n8n-db-$(date +%F).sql.gz"

docker run --rm \
  -v n8n_data:/source:ro \
  -v "$PWD/backup":/backup \
  alpine sh -c \
  'tar -czf /backup/n8n-data-$(date +%F).tar.gz -C /source .'

tar -czf "backup/n8n-config-$(date +%F).tar.gz" \
  .env compose.yaml Caddyfile

docker compose start n8n n8n-runner

包含 .env 的归档中有敏感密钥:请对其加密,并存放在 VPS 之外。还应定期通过测试恢复来验证备份。

更新前先进行备份并阅读版本说明:

cd /opt/n8n
docker compose pull
docker compose up -d
docker compose ps

任务运行器和主容器必须使用相同的版本标签。

何时需要扩展

在出现真实负载之前,不要一开始就部署 Redis 和多个 worker。单个 n8n 实例配合 PostgreSQL 更容易维护,通常足以处理小型内部流程。

当长任务拖慢 webhook、许多工作流同时启动,或文件处理经常占满全部内存时,就需要 queue mode。此时主实例负责接收事件,Redis 分发任务,worker 并行执行。所有组件都必须连接同一个 PostgreSQL,并使用相同的 N8N_ENCRYPTION_KEY

n8n 应选择怎样的 VPS

对于 n8n、PostgreSQL、Caddy 和任务运行器这套组合,从 2 vCPU、4 GB RAM 和 NVMe 硬盘起步比较合理。在 tropic.host 上,对应的是 Light 套餐:2 vCPU、4 GB RAM 和 25 GB NVMe。对于不进行重度文件处理的首批生产工作流,这已经足够。

如果要处理文档、大型数据集或大量并行 AI 工作流,最好选择 8 GB RAM。稳定的网络同样重要:webhook、OAuth 回调和定时任务必须始终保持可用。

总结

n8n 可以将重复操作变成清晰直观的流程图:现成节点加快部署,HTTP Request 可以连接几乎任意 API,Code node 则允许补充自己的逻辑。

自托管版本让你掌控服务器和数据库,但也要求配置 HTTPS、限制密钥权限、清理历史记录并建立经过验证的备份。请将 N8N_ENCRYPTION_KEY 与 PostgreSQL 一起保存:没有它,恢复后的凭据无法解密。

FAQ

n8n 可以免费使用吗?

可以。Community Edition 可以免费部署在自己的服务器上,用于个人和内部流程。fair-code 许可证限制将托管的 n8n 作为独立 SaaS 转售。

可以不使用域名安装 n8n 吗?

本地测试可以。对于公开 webhook 和 OAuth,最好使用域名和 HTTPS。

n8n 需要多少内存?

简单的个人工作流通常 2 GB RAM 就够用。n8n 与 PostgreSQL、Caddy 和任务运行器一起运行时,4 GB 更合理;文件处理和并行执行可能需要 8 GB 或更多。

所有数据都会留在 VPS 内吗?

只有工作流没有发送到外部的数据才会留在 VPS 内。数据库和执行历史位于 VPS 上,但 Telegram、CRM 或外部 AI 模型节点会把选中的数据发送到对应服务。

n8n 备份中应包含什么?

PostgreSQL 转储、n8n_data 卷、compose.yamlCaddyfile,以及包含 N8N_ENCRYPTION_KEY.env。请将加密后的备份存放在 VPS 之外,并通过恢复测试验证它。