关于 n8n-self-hosting
面向希望自托管 n8n 的操作者,提供在新 Linux VM 上通过 Docker Compose 和 Caddy 部署 HTTPS 实例的流程。指南涵盖单实例与队列模式、密钥管理、验证及后续维护。
主要功能
- 01提供单实例和队列部署方案
- 02使用 Docker Compose 与 Caddy
- 03配置 HTTPS 与 Let's Encrypt
- 04指导密钥生成和环境变量保护
- 05验证服务健康状态与外部访问
- 06涵盖更新、备份和恢复
适用场景
- 01在新 Linux VM 上部署 n8n
- 02按负载选择单实例或队列架构
- 03排查 DNS、TLS 或服务健康问题
- 04规划实例更新与灾难恢复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ czlonkowski/ n8n-mcp --skill n8n-self-hosting安装后在 Claude Code 中输入/n8n-self-hosting确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CREDENTIAL_OVERWRITES.mdDAY2.mdQUEUE_MODE.mdREADME.mdSECURITY.mdSINGLE_MODE.mdassets/.env.queue.example.env.single.exampleCaddyfiledocker-compose.queue.ymldocker-compose.single.ymlinit-data.sh详细介绍
部署自托管 n8n
此技能可将一台全新的 Linux 虚拟机(Ubuntu/Debian,通过 root 或 sudo SSH 访问)部署为运行中的生产级 n8n,并启用 HTTPS,使用 Docker Compose,并由 Caddy 提供服务(自动配置 Let's Encrypt TLS)。 适用于基于 Docker 的自托管 n8n,不适用于 n8n Cloud,也不用于构建工作流 (这属于本套指南的其他部分)。
有两种部署模式。两种架构不同,请先选择模式,再开始操作。
你将通过 SSH 完成整个流程:预检 → 安装 Docker → 部署项目 →
生成密钥 → 启动 → 验证 TLS → 移交。模板文件位于 assets/;
各模式的详细说明和安全细节见下方列出的参考文件。
规则 0 — 选择模式(询问用户)
不要猜测。先询问,再确定一种模式:
| 单实例 / 常规 | 队列 | |
|---|---|---|
| 进程 | 一个 n8n | 主进程 + N 个工作进程 |
| 额外服务 | 无(SQLite) | Redis(队列)+ Postgres(数据库) |
| 执行工作流 | 在主进程中 | 在工作进程上并行执行 |
| 适用于 | 1 位用户、轻到中等负载、运维最简单 | 高吞吐量、繁重或长时间执行、水平扩展 |
| Compose | assets/docker-compose.single.yml | assets/docker-compose.queue.yml |
| 深入了解 | SINGLE_MODE.md | QUEUE_MODE.md |
如果不确定,请从单实例开始——这是最简单且正确的方案,适用于大多数需求。之后迁移到队列模式意味着更换 compose 文件,并将 SQLite 迁移到 Postgres。因此,如果用户已经预期会有实际的大量负载,请直接从队列模式开始。
规则 1 — 密钥卫生(绝不妥协)
这方面的失误会泄露客户端凭据。务必谨慎:
- 在目标机器上为每个密钥生成全新的值。 绝不要将其他 n8n 实例的加密密钥、数据库密码或
.env复制到此实例。请参阅SECURITY.md中的openssl命令。 - 密钥只能存放在
.env中(权限模式为 600),并在 compose 文件中通过${VAR}引用。绝不要将密钥直接写入docker-compose.yml、Caddyfile 或任何会提交的文件。 N8N_ENCRYPTION_KEY至关重要。 它会加密所有已存储的凭据。如果丢失或更改,所有已保存的凭据都将无法解密。请显式设置此值,并告知用户将其备份到目标机器之外。除了移交所必需的内容外,不要将其输出到长期保留的日志或聊天记录中。- 绝不要暴露内部服务。 只有 Caddy(80/443 端口)可以公开访问。n8n(5678 端口)、Postgres(5432 端口)、Redis(6379 端口)都必须留在私有 Docker 网络中——模板已省略它们的主机端口映射。不要添加这些映射。
.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;每个工作进程需要约 1–2 GB)。
- 可选模块 — 某些功能(目前为 Agents)属于后端模块,只有列入
N8N_ENABLED_MODULES后才会启用。只有用户提及时才询问;如果用户提到,请在启用前阅读QUEUE_MODE.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 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/。 - 将模板文件传到服务器。 它们位于你本机上此技能的
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
- 所选 compose 文件 →
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/健康状态(队列模式:先确认 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说明了这条规则。 - 打开
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)。
参考文件
SINGLE_MODE.md— 单实例特定说明、SQLite 与 Postgres 的区别,以及何时应迁移到队列。QUEUE_MODE.md— 队列架构、工作进程/并发/扩展、共享加密密钥、主实例与工作进程的环境变量一致性规则、可选后端模块(N8N_ENABLED_MODULES,例如 Agents)、二进制数据(database模式——队列模式不支持文件系统;S3/Azure 属于企业版)、Webhook 处理器、多主实例许可。SECURITY.md— 生成密钥、加密密钥规则、完整的安全加固清单(关闭遥测、阻止访问环境变量、公共 API、防火墙、安全 Cookie)。CREDENTIAL_OVERWRITES.md— 托管 OAuth:在整个实例范围内注册一个 OAuth 应用,这样用户就不会看到客户端 ID/密钥(自托管环境中的“使用 Google 登录”)。端点与环境变量的选择、强制要求的端点身份验证令牌、父类型继承、持久化和工作进程重新加载。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。
如果本技能与在线文档不一致,请以文档为准并告知用户。