mcpField
N
n8n-self-hosting

n8n-self-hosting

github.com/czlonkowski云与 DevOps6.5k2.0k 次安装4 天前更新
代码仓库

关于 n8n-self-hosting

面向运维人员的 n8n Linux 虚拟机部署指南,使用 Docker Compose、Caddy 和 HTTPS。内容涵盖单进程与队列模式选择、安装、安全、验证及维护。

主要功能

  1. 01单实例与队列部署方案
  2. 02Docker Compose 和 Caddy 配置
  3. 03HTTPS 证书验证
  4. 04密钥与网络安全指导
  5. 05部署健康检查

适用场景

  1. 01在全新 Linux 虚拟机上运行 n8n
  2. 02按预期负载选择部署模式
  3. 03检查 HTTPS 和服务状态
  4. 04保护密钥及内部服务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/czlonkowski/n8n-skills --skill n8n-self-hosting

安装后在 Claude Code 中输入/n8n-self-hosting确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CREDENTIAL_OVERWRITES.md
DAY2.md
QUEUE_MODE.md
README.md
SECURITY.md
SINGLE_MODE.md
TASK_RUNNERS.md
assets/
.env.queue.example
.env.single.example
Caddyfile
docker-compose.queue.yml
docker-compose.single.yml
init-data.sh

详细介绍

部署可自托管的 n8n

此技能可将一台全新的 Linux 虚拟机(Ubuntu/Debian,使用 root 或 sudo SSH)部署为可运行、启用 HTTPS、可用于生产环境的 n8n,通过 Docker Compose 在 Caddy 后运行(自动配置 Let's Encrypt TLS)。此方案适用于 Docker 上可自托管的 n8n,不适用于 n8n Cloud,也不用于构建工作流(本资源包的其他部分会介绍)。

有两种部署模式。两种架构有所不同,因此开始操作前请先选择模式。

你将通过 SSH 完成端到端部署:预检查 → 安装 Docker → 部署项目 → 生成密钥 → 启动 → 验证 TLS → 交接。模板文件位于 assets/ 中,各模式的详细说明和安全注意事项见下文列出的参考文件。

规则 0 — 选择模式(询问用户)

不要猜测。先询问,然后确定一种模式:

单机 / 常规队列
进程一个 n8n主进程 + N 个工作进程
额外服务无(SQLite)Redis(队列)+ Postgres(数据库)
执行工作流在主进程中由工作进程并行执行
适用场景1 位用户、轻度/中度负载、运维最简单高吞吐量、繁重/长时间执行、水平扩展
Composeassets/docker-compose.single.ymlassets/docker-compose.queue.yml
深入了解SINGLE_MODE.mdQUEUE_MODE.md

如果不确定,请从单机模式开始——它是最简单且正确的选择,适用于大多数需求。之后切换到队列模式需要替换 compose 文件,并将 SQLite 迁移到 Postgres;因此,如果用户已经预计会有较大流量,请直接从队列模式开始。

规则 1 — 密钥卫生(不可妥协)

这里一旦操作失误,就会泄露客户端凭据。务必谨慎:

  1. 在目标机器上为每个密钥重新生成。 切勿将其他 n8n 实例的加密密钥、数据库密码或 .env 复制到此实例。SECURITY.md 中提供了 openssl 命令。
  2. 密钥只能存放在 .env 中(权限模式为 600),并通过 compose 中的 ${VAR} 引用。切勿将密钥直接写入 docker-compose.yml、Caddyfile 或任何会提交的内容中。
  3. N8N_ENCRYPTION_KEY 至关重要。 它用于加密所有已存储的凭据。如果丢失或发生变化,所有已保存的凭据都将无法解密。请明确设置,并提醒用户将其备份到机器之外。除了交接所需内容外,不要将其输出到长期日志或聊天记录中。
  4. 绝不公开内部服务。 仅 Caddy(80/443)可公开访问。n8n(5678)、Postgres(5432)、Redis(6379)必须留在私有 Docker 网络中——模板已省略它们的主机端口映射。不要添加这些映射。
  5. .env 和 Caddy 的 caddy_data 卷(已签发的证书和 ACME 账户密钥)不得作为共享文件。 如果你在 git 仓库中操作,请在提交前确认 .env 已被 git 忽略。

预先收集的输入信息

  • SSH 目标 — user@host 以及身份验证方式(密钥路径,或用户确认 Agent 已有访问权限)。使用 root 或 sudo 用户。
  • 域名 — n8n 将使用的完整主机名,例如 n8n.example.com(→ SUBDOMAIN=n8n,DOMAIN_NAME=example.com)。用户必须能控制其 DNS。
  • TLS 邮箱 — 用于 Let's Encrypt(SSL_EMAIL)。
  • 时区 — Schedule/Cron 节点使用的 IANA 名称(例如 Europe/Warsaw),否则使用 Etc/UTC。
  • 模式 — 单机或队列(规则 0)。队列模式 → 确认服务器有足够的 RAM(最低约 4 GB;每个 worker 需要约 1–2 GB)。
  • 可选模块 — 部分功能(目前为 Agents)属于默认关闭的后端模块,只有列入 N8N_ENABLED_MODULES 后才会启用。只有用户主动提及时才询问;如果用户提及,请在启用前阅读 QUEUE_MODE.md 的模块部分,因为队列模式下还必须让 worker 能访问这些模块。
  • Python Code 节点 / 谁会编辑工作流 — 询问 “工作流会使用 Python Code 节点吗?除了你之外,还会有人编辑工作流吗?” 任何一项回答“是”,都意味着要将 task runner 设为 external mode:使用 n8nio/runners sidecar(队列模式下每个 worker 配置一个)。官方的 n8nio/n8n 镜像不包含 Python 3,因此在默认的 internal mode 下,每个 Python Code 节点都会失败,并显示 Python runner unavailable: Python 3 is missing from this system。请在第 3 步之前阅读 TASK_RUNNERS.md。

部署流程

请按顺序完成以下步骤。SINGLE_MODE.md / QUEUE_MODE.md 提供各模式的具体命令;SECURITY.md 介绍密钥生成和加固;DAY2.md 介绍更新/备份/恢复。

1. 部署前检查(越早发现问题,修复成本越低)
  • 通过 SSH 登录;确认操作系统类似 Debian/Ubuntu(. /etc/os-release)。
  • DNS 必须已指向服务器。 将服务器的公网 IP(curl -s ifconfig.me)与 dig +short <fqdn> 的结果比较(在服务器上运行,并最好也在你的笔记本电脑上运行)。如果两者不一致,请停止 — Caddy 的 ACME 验证会失败。请让用户创建 A 记录,等待其生效后再继续。
  • 端口 80 和 443 必须可从互联网访问。检查主机防火墙以及任何云安全组 / 网络防火墙(Hetzner Cloud、AWS SG 等)——这些位于服务器之外,是常见的隐性拦截因素。
2. 安装 Docker(如果尚未安装)
  • 检查 docker --version 和 docker compose version。如果缺少 Docker,请安装 Docker Engine 和 Compose 插件(在 Ubuntu/Debian 上使用 Docker 官方的 get.docker.com 脚本即可)。 继续之前,请重新检查 docker compose version。
3. 部署项目文件
  • 选择 DATA_FOLDER — 一个绝对路径,例如 /opt/n8n。.env 中的 DATA_FOLDER 值必须与此目录完全一致(compose 会挂载 ${DATA_FOLDER}/caddy_config/Caddyfile,而 init-data.sh 通过相对的 ./ 路径挂载),因此务必始终在此目录下运行 docker compose。创建该目录,以及其中的 caddy_config/ 和 local_files/。
  • 将模板文件传到服务器。 这些文件位于你本机上此 skill 的 assets/ 目录中,而不是服务器上——请逐个传输。可以使用 scp 上传,或者(无需本地副本)通过 SSH 写入各文件的内容,例如: ssh <target> 'cat > <DATA_FOLDER>/docker-compose.yml' < assets/docker-compose.single.yml。 请使用以下准确文件名放置文件:
    • 选定的 compose → <DATA_FOLDER>/docker-compose.yml(重命名为此准确名称)
    • Caddyfile → <DATA_FOLDER>/caddy_config/Caddyfile
    • 仅队列模式: init-data.sh → <DATA_FOLDER>/init-data.sh,然后运行 chmod +x
    • 对应的 .env.*.example → <DATA_FOLDER>/.env
  • External task runner(Python): 现在将 runner 环境变量和 task-runners sidecar 添加到 compose 中(TASK_RUNNERS.md 提供各模式对应的代码片段)。在第 4 步生成 N8N_RUNNERS_AUTH_TOKEN,与其他密钥一并生成。
4. 填写 .env + 生成密钥
  • 设置 DATA_FOLDER、DOMAIN_NAME、SUBDOMAIN、SSL_EMAIL、GENERIC_TIMEZONE。
  • 在主机上使用 openssl 生成每个密钥(SECURITY.md 中有相关命令),并将其写入 .env,替换对应的 REPLACE_WITH_… 占位符:N8N_ENCRYPTION_KEY;队列模式还需要 POSTGRES_PASSWORD + POSTGRES_NON_ROOT_PASSWORD。
  • 启动前,确认没有未设置的密钥:grep REPLACE_WITH_ .env 必须无任何输出——遗留的占位符会变成字面密码,导致 Postgres/n8n 无法连接。
  • 执行 chmod 600 .env。记录加密密钥,以便用户备份到主机外。
5. 防火墙
  • 使用 ufw:允许 OpenSSH + 80 + 443,然后启用防火墙。不要开放 5678/5432/6379。
6. 启动
  • 执行 cd <DATA_FOLDER> && docker compose up -d。
  • 队列模式会启动 Redis + Postgres + 主服务 + 工作进程(工作进程通过 replicas 启动)。要增加容量:docker compose up -d --scale n8n-worker=N。
7. 验证(未完成此项前不要宣告成功)
  • docker compose ps — 每个服务都应为 Up/healthy(队列模式:先确认 postgres 和 redis 为 healthy)。
  • 确认 n8n 本身已启动(内部): docker compose exec n8n wget -qO- http://localhost:5678/healthz → {"status":"ok"}。这样可以区分“n8n 正在运行”和“TLS 尚未就绪”。
  • 确认已签发证书: docker compose logs caddy | grep -i 'certificate obtained'。首次启动时,ACME 可能需要一两分钟;在完成之前,访问公开的 https:// 地址会发生 TLS 错误——这表示证书仍在等待签发,并不表示 n8n 已停止运行。
  • 确认可从外部访问(带重试): curl -fsS --retry 5 --retry-delay 10 https://<fqdn>/healthz → {"status":"ok"}。(/healthz 只能证明进程可访问;/healthz/readiness 还会确认数据库已连接并完成迁移——排查启动循环时请使用此端点。)
  • 队列模式 — 主服务和工作进程的配置必须一致。 对比它们的环境变量: diff <(docker compose exec -T n8n env | sort) <(docker compose exec -T --index 1 n8n-worker env | sort)。 只有公开 URL/代理变量应该不同。其他任何差异都表示某个行为设置已传递给主服务,却未传递给工作进程——而工作流由工作进程执行,因此会在运行时而非启动时因某个节点配置不一致而失败。QUEUE_MODE.md 解释了此规则。
  • 外部任务运行器: docker compose logs n8n | grep 'Registered runner' 必须显示 launcher-javascript 和 launcher-python(队列模式:检查每个工作进程)。然后对 Python Code 节点进行冒烟测试(TASK_RUNNERS.md → Verify)。
  • 打开 https://<fqdn> → 所有者设置页面。第一个完成注册表单的人将获得该实例的所有权——暴露在外且尚未设置所有者的实例存在被抢先认领的风险,因此请立即创建所有者账户,然后再分享 URL。启用 2FA。(自动化部署也可以通过环境变量预先配置所有者——参见 SECURITY.md 中所有者对应的条目。)
8. 交接
  • 向用户提供:URL、项目所在位置、需要妥善保存的加密密钥,以及来自 DAY2.md 的日常维护基础知识(更新 / 备份 / 恢复)。

不要做的事

  • 不要跳过 DNS/端口预检。 A 记录错误或云防火墙未开放,是 Caddy 无法获取证书、n8n 看起来“坏了”的 首要原因。
  • 不要将 5678/5432/6379 发布到主机。 Caddy 通过专用网络访问 n8n。
  • 不要重复使用其他实例的加密密钥或 .env。 每台主机都要使用全新的密钥。
  • 不要在 SQLite 上运行队列模式。 队列需要 Postgres(模板已配置好)。
  • 不要将密钥放在 docker-compose.yml 或 Caddyfile 中。 只放在 .env 中。
  • 不要只在主节点上添加行为相关的环境变量(队列模式)。 模块、数据库、队列、二进制数据和加密设置都应放在共享的 x-n8n-env 锚点中,以便工作节点也能获取;只有公共 URL/代理变量仅用于主节点。参见 QUEUE_MODE.md。
  • 不要盲目使用 :latest。 固定 N8N_IMAGE_TAG;谨慎更新(DAY2.md)。
  • 不要承诺内部模式下的标准镜像支持 Python Code 节点。 它们需要 n8nio/runners sidecar,且版本必须与 n8n 完全一致,并在启动器配置中将导入项加入允许列表。默认情况下,连 import json 都会被拒绝。参见 TASK_RUNNERS.md。
  • 外部运行器启用后,不要对队列工作节点使用 --scale。 一个 sidecar 只能服务一个工作节点。应添加工作节点 + 运行器配对(TASK_RUNNERS.md)。

参考文件

  • SINGLE_MODE.md — 单实例相关说明、SQLite 与 Postgres 的选择,以及何时升级到队列模式。
  • QUEUE_MODE.md — 队列架构、工作节点/并发/扩展、共享加密密钥、主节点与工作节点之间的环境变量一致性规则、可选后端模块(N8N_ENABLED_MODULES,例如 Agents)、二进制数据(database 模式——队列模式不支持文件系统;S3/Azure = Enterprise)、Webhook 处理器、多主节点许可。
  • SECURITY.md — 生成密钥、加密密钥规则、完整的安全加固清单(关闭遥测、阻止访问环境变量、公共 API、防火墙、安全 Cookie)。
  • CREDENTIAL_OVERWRITES.md — 托管 OAuth:在整个实例范围内注册一个 OAuth 应用,让用户永远看不到客户端 ID/密钥(自托管环境中的“使用 Google 登录”)。端点与环境变量的选择、必需的端点身份验证令牌、父类型继承、持久化和工作节点重新加载。
  • TASK_RUNNERS.md — 外部模式下的任务运行器:Python Code 节点为何需要 n8nio/runners sidecar、单实例模式的 compose 片段和队列模式下每个工作节点对应一个 sidecar 的模式、通过 /etc/n8n-task-runners.json 将 Python/JS 模块加入允许列表、内置拒绝列表、验证、故障特征,以及同时升级 n8n 和运行器。
  • DAY2.md — 安全地更改设置(环境变量)、更新镜像、备份(加密密钥 + 卷 + Postgres)和恢复。
  • assets/ — 模板:docker-compose.single.yml、docker-compose.queue.yml、Caddyfile、.env.single.example、.env.queue.example、init-data.sh。

权威上游参考资料:官方托管文档位于 https://docs.n8n.io/deploy/host-n8n(在 2026 年年中从旧的 /hosting/ 路径重组而来—— 请优先使用这些 URL)。环境变量参考索引位于 https://docs.n8n.io/deploy/host-n8n/configure-n8n/basic-configuration/use-environment-variables。 如果本文档与实时文档不一致,请以文档为准并告知用户。

评论

支持 Markdown