我第一次接触 n8n 是在一个加班到深夜的项目里。产品经理临时要我每天把 CRM 里新增的客户信息同步到飞书表格,还得给对应的销售发提醒。手动做了一周后我实在受不了,开始在网上乱翻自动化工具。Zapier 的免费额度太小,Make 的可视化让我有点晕,直到有人在一个技术群里丢了一句“你试过 n8n 吗”,我才算真正推开了这扇门。这篇文章想做的,就是把我从“完全不知道 n8n 能干什么”到“能自己搭一条稳定流程”这段路上踩过的东西,按学习顺序重新捋一遍,顺便把自动化思维这件事说清楚。
1.1 n8n 是什么:节点、触发器、工作流与执行模型
如果要用一句话说清楚 n8n,我会说它是一个“把不同软件用积木方式连起来”的工具。这个积木的最小单位叫节点。每个节点负责一件事,比如读取一封邮件、查询一条数据库记录、调用一次 OpenAI 接口、往 Slack 发一条消息。节点本身不复杂,复杂的是它接收什么数据、输出什么数据,以及下一个节点怎么用这些数据。我刚开始的时候总想把节点当成一个黑盒按钮,点一下就完事。真正用起来才发现,理解节点的输入输出结构才是关键,n8n 里的数据基本都是以 JSON 形式在节点之间流动的。
触发器是另一种节点,它决定了工作流什么时候开始跑。常见的触发方式有定时触发、Webhook 触发、应用事件触发,还有手动触发。我最早用的是定时触发,每天早上八点自动跑一次,把前一天的数据汇总发到群里。后来开始用 Webhook 触发,外部系统一有事件就推过来,流程立刻响应,那种“事情发生即处理”的感觉比定时轮询舒服太多。触发器选得对不对,直接决定了整条工作流的响应速度和资源消耗。
工作流就是把触发器和若干普通节点按顺序或分支连起来的一条链路。它的执行模型是逐节点、按连接传递数据的。上游节点跑完,输出会作为输入传给下游节点。执行记录可以在 n8n 界面里看到,每个节点收到了什么、输出了什么、有没有报错,都清清楚楚。我踩过的一个坑是,节点执行顺序并不是写死的,而是按照连接关系和数据依赖来的。一条分支上的节点可能并行跑,这在一开始让我很困惑,后来才慢慢习惯用“数据流”而不是“代码行”的思路去看待整个流程。
1.2 n8n 的核心优势与适用边界:对比 Zapier、Make、Airflow
我三个工具都用过一阵子,说点真实的感受。Zapier 最容易上手,界面友好,集成数量多,但免费版限制很紧,复杂一点的逻辑就得付费,而且很多操作被封装得太深,想改底层行为几乎不可能。Make 的可视化做得漂亮,分支和循环的处理比 Zapier 灵活不少,但它的操作单元是按“operation”计费的,流程一复杂成本就上来了。n8n 最大的不同在于它开源、可以自托管,节点里的逻辑你能看到、能改、能自己写代码节点去扩展。对于想省钱又愿意花点时间折腾的人来说,这个自由度很值钱。
不过 n8n 也不是万能药。它的学习曲线比 Zapier 陡,尤其是涉及表达式、数据映射、自托管部署这些部分,新手很容易卡住。我一开始就被“表达式”和“代码节点”之间的选择搞晕过。另外 n8n 的官方集成数量虽然不少,但和 Zapier 那种几千个应用比起来还是有差距,有些冷门服务只能靠 HTTP Request 节点自己调 API。把 n8n 和 Airflow 放在一起比也很有意思,Airflow 更适合数据工程团队做大规模、重调度的批处理任务,n8n 更偏向业务自动化和轻量级集成。两者定位不同,硬要比个高下没太大意义。
我的判断标准是这样的:如果你需要快速打通几个 SaaS 工具、逻辑不复杂、预算有限,Zapier 或 Make 够用。如果你希望流程可控、能自托管、愿意写点代码、未来可能接入 AI 或内部系统,n8n 更合适。如果你是在做数据仓库级别的任务编排,Airflow 仍然是更专业的选择。工具没有绝对的好坏,关键看你手上这件事需要什么。
1.3 n8n 常见应用场景:数据同步、Webhook 集成、AI 自动化与内部工具
数据同步是我用得最多的场景。比如把表单提交的数据写进数据库、把电商订单同步到 ERP、把多个渠道的客户信息汇总到一张总表。这类任务的特点是有明确的触发条件、有固定的字段映射、偶尔需要做去重和格式转换。n8n 在这类场景里表现很稳,定时触发加几个数据处理节点就能跑起来。我做过一个把微信公众号文章自动同步到 Notion 数据库的流程,跑了几个月基本没出过问题。
Webhook 集成是另一块高频区域。任何能发 HTTP 请求的系统都可以通过 Webhook 触发 n8n 工作流。我用它接过来自 GitHub 的 push 事件、来自支付平台的交易通知、来自客服系统的工单创建事件。Webhook 的好处是实时性,事情发生的那一刻流程就动了。用 Webhook 的时候要注意安全,比如加一个密钥校验,不然任何人都能往你的工作流里推数据,这一点我在早期完全没意识到。
AI 自动化和内部工具是我最近半年花时间最多的方向。n8n 里有专门的 AI 节点,也可以直接用 HTTP Request 调用大模型接口。我做过智能摘要工作流,把长文章丢进去,输出一段摘要发到群里。也做过自动分类流程,让模型判断客户留言是咨询、投诉还是合作意向,然后路由到不同的人处理。内部工具方面,我用 n8n 搭过简易的审批流、日报自动生成器、服务器告警转发器。这些工具单独开发一个系统不划算,用 n8n 拼出来刚刚好。
1.4 学习路线图:快速上手、工作流自动化教程与自托管部署教程的衔接
我回头看自己的学习路径,大致分成三个阶段。第一阶段是快速上手,目标就是跑通一个最简单的流程,比如定时发一条消息到 Telegram 或者把一个表单数据写进 Google Sheets。这个阶段不需要理解太多概念,跟着界面点一点,感受一下节点连起来之后自动执行的那一下惊喜就够了。很多人卡在第一步就是因为想先把所有概念搞懂再动手,其实反过来更有效,先让流程跑起来,遇到问题再回去查。
第二阶段是工作流自动化教程的深入。这个阶段我开始认真学数据映射、表达式、条件分支、循环、错误处理这些内容。我花了不少时间在“为什么这个节点拿不到上一个节点的数据”这种问题上,后来才明白是字段路径写错了或者数据结构没对上。这个阶段最好的学习方式是给自己找一个真实的小需求,比如自动整理每周的销售数据,然后逼着自己用 n8n 从头搭到尾。教程能教你节点怎么用,但只有真实需求能教你流程怎么设计。
第三阶段是自托管部署。当你开始把 n8n 用在正式工作里,云版本的限制就会慢慢显现,比如执行次数、数据存储位置、环境变量控制。这时候学 Docker 部署、数据库配置、反向代理、备份升级这些内容就变得必要了。我在这块踩的坑最多,端口冲突、权限问题、时区不对、Webhook 回调地址配错,几乎每种都遇到过。这三块内容不是严格串行的,很多时候是交叉着学的。但整体上,先上手、再深入流程、最后搞部署,这个顺序对我来说是最顺的。
上一章聊完了 n8n 是什么、能干什么,以及我自己的学习路径。这一章我打算把手弄脏,从打开界面开始,一步一步走到能搭出靠谱的生产级流程。说实话,这部分内容是我踩坑最多、也最有话想说的地方。每个小节我都会尽量讲清楚“我当时是怎么做的”“哪里卡住了”“后来怎么绕过去的”,希望能让你少走一些弯路。
2.1 环境准备与界面导览:云版本、本地启动与项目结构
我最开始用的是 n8n 云版本,注册完就能用,不用折腾环境。对于完全没接触过的人来说,云版本的优势很明显:打开浏览器就能开始拖节点,前两周的免费额度基本够你把常见功能试一遍。我记得第一个晚上就搭了一个定时抓 RSS 然后发到邮箱的流程,跑通那一刻的成就感特别强。云版本的短板也很直接,执行次数有限制、数据存在别人服务器上、有些环境变量不能随便改,用到后面就会觉得手脚被绑住了。
后来我转向本地启动,用的是 npx n8n 这条命令。这种方式适合快速验证想法,不需要 Docker,也不需要配置文件,一条命令就跑起来了。默认访问地址是 localhost:5678,第一次打开会让你设置 owner 账号。本地启动的缺点是每次都要开着终端,电脑一关流程就停了。我有一段时间把它跑在一台常年不关的旧笔记本上,勉强当个小服务器用。等我开始认真对待这件事之后,才切到 Docker 方案,这块内容我会在第三章详细展开。
界面本身不复杂,左侧是节点面板,中间是画布,右侧是节点配置区。画布上你可以拖拽节点、连线、放大缩小,顶部有保存、执行、激活这几个按钮。我建议新手花十分钟把每个按钮点一遍,尤其是右上角的“Executions”页面,后面调试全靠它。项目结构方面,如果你是自托管,数据默认存在 ~/.n8n 目录下,里面会有数据库文件、加密密钥、配置文件。搞清楚这些文件放在哪,对后面做备份和迁移特别重要。
2.2 第一个工作流:触发器、节点配置、连接与手动执行
我的第一个正式工作流是“每天早上八点把天气发到 Telegram”。听起来很傻,但它把触发器、节点配置、连接、执行这四个核心动作全串了一遍,作为练手特别合适。触发器我选的是 Schedule Trigger,配置成每天早上八点触发一次。这里有个小细节,时区默认跟随服务器,如果你在国内用云版本,记得在设置里改成 Asia/Shanghai,不然触发时间会偏八个小时。
节点配置这块,我用了一个 HTTP Request 节点去调天气 API,再用一个 Telegram 节点把结果发出去。配置 HTTP Request 的时候要填 URL、请求方法、查询参数,如果 API 需要密钥,还得在 Headers 里加上。Telegram 节点需要先创建凭证,也就是把 Bot Token 填进去。凭证这个概念在 n8n 里很重要,它和节点是分开管理的,一个凭证可以被多个节点复用。我第一次配的时候把 Token 直接写在了节点参数里,后来才知道这样做既不安全也不方便维护。
连接就是把节点从左到右串起来,鼠标按住节点右侧的小圆点拖到下一个节点左侧就行。连好之后点顶部的“Execute Workflow”按钮,整个流程会手动跑一遍。手动执行的好处是你能看到每个节点的输入输出,哪个节点报错一眼就能看出来。我当时遇到的问题是 Telegram 节点一直报“chat not found”,查了半天才发现是 chat ID 填错了。这种低级错误在新手阶段非常常见,手动执行加上看执行日志,基本能解决八成问题。
2.3 数据映射与表达式:JSON、变量、函数节点与代码节点
数据映射是我认为 n8n 学习曲线里最陡的一段。节点之间传的数据是 JSON 数组,每个元素叫一个 item。上一个节点输出了什么字段,下一个节点要用的字段路径怎么写,这些东西一开始特别容易搞混。我记得有一次明明看到上一个节点输出了 name 字段,下一个节点里就是取不到,折腾了半小时才发现数据结构是嵌套的,正确路径应该是 $json.body.name 而不是 $json.name。这种错误一旦理解之后就再也不会犯了,但第一次遇到真的很抓狂。
表达式是 n8n 里非常强大的一个东西,用 {{ }} 包起来,可以写类似 JavaScript 的语法。你可以用它做字符串拼接、日期格式化、条件判断、数组操作。我常用的是 {{ $json.field }} 取当前节点的数据,{{ $node["节点名"].json.field }} 取指定节点的数据,还有 {{ $now }} 取当前时间。表达式的学习成本不算高,但需要你理解数据在节点之间是怎么流动的。我建议新手先在简单场景里用表达式,比如把两个字段拼成一个字符串,熟悉之后再处理复杂逻辑。
当表达式搞不定的时候,就该请出 Code 节点了。Code 节点允许你写真正的 JavaScript,对每个 item 做任意处理。我做过一个需求,要把一段文本里的所有邮箱地址提取出来,用表达式写会非常别扭,用 Code 节点三行正则就搞定了。Function 节点是老版本里的叫法,现在基本被 Code 节点取代。我的经验是,能用节点配置解决的就别写代码,能用表达式解决的就别开 Code 节点,因为代码越多的流程,后期维护成本越高。这个平衡点需要自己摸索。
2.4 流程控制:条件分支、循环、合并、等待与子工作流
流程控制是让工作流从“能用”变成“好用”的关键。IF 节点是最常用的分支节点,它根据条件把数据分流到 true 和 false 两条路径。我做过一个客户留言分类的流程,先用 AI 判断留言类型,然后用 IF 节点把咨询、投诉、合作意向分别路由到不同的处理分支。IF 节点支持多个条件组合,AND 和 OR 都能配。用的时候要注意,条件比较的类型要对上,字符串和数字直接比会出问题。
循环在 n8n 里有两个层面。一个是节点本身对多个 item 的自动遍历,比如你有一个包含十条数据的数组,下游节点会默认执行十次。另一个是 Loop Over Items 节点,用来处理需要分批或者需要等待的场景。我用它做过批量发送邮件的流程,每批发五封,中间等一下,避免被邮件服务商限流。合并节点用来把多条分支的数据合在一起,有 append、merge by key、combine 几种模式,选错了数据就会乱。等待节点很简单,就是让流程停一段时间再继续,适合做轮询或者限速。
子工作流是我最近才认真用起来的功能。它允许你把一段常用逻辑抽出来做成独立工作流,然后在主工作流里用 Execute Workflow 节点调用。好处是复用和模块化,比如我把“发送企业微信通知”这段逻辑做成了一个子工作流,十几个主流程都在调它,改一处就全改了。子工作流之间可以传数据,输入输出都是 JSON,用起来和普通节点差不多。我唯一的建议是子工作流的命名要清楚,不然工作流一多,自己都记不住哪个是干嘛的。
2.5 常用集成实战:HTTP Request、Webhook、数据库、表格与消息通知
HTTP Request 节点是我用得最多的节点,没有之一。只要一个服务提供了 API,你就能用它接进来。配置的时候要注意请求方法、认证方式、请求体格式这几项。GET 请求的参数一般放在 Query 里,POST 请求的数据放在 Body 里,Body 又分 JSON、Form、Raw 几种格式,选错了对方服务会直接报 400。我还踩过一个坑,有些 API 要求 Content-Type 必须是 application/json,n8n 默认不一定带上,需要手动在 Headers 里加。
Webhook 节点是另一个高频节点,它让 n8n 能被动接收外部事件。配置好之后会给你一个 URL,把这个 URL 填到第三方服务的 Webhook 设置里就行。我用它接过 GitHub 的 push 事件、Stripe 的支付通知、还有自己写的小脚本上报的数据。Webhook 分测试 URL 和生产 URL,测试 URL 只在点击“Listen”的时候有效,生产 URL 需要激活工作流才生效。我早期经常搞混这两个,明明工作流激活了却收不到数据,后来才发现是用错了 URL。
数据库节点支持 MySQL、PostgreSQL、MongoDB 等常见数据库,配置好连接信息之后就能执行查询、插入、更新。我用它做过把表单数据写进 Postgres,也做过从 MySQL 里拉数据生成报表。表格类集成主要是 Google Sheets 和 Airtable,这两个我用得不多,但身边朋友反馈都挺好。消息通知节点覆盖面很广,Slack、Telegram、企业微信、钉钉、邮件都有。我现在的习惯是每个重要工作流跑完之后都发一条通知到企业微信群,成功了发绿色卡片,失败了发红色卡片,一眼就能看出系统状态。
2.6 错误处理与调试:重试、错误工作流、执行日志与测试策略
错误处理这块我吃过不少亏,所以我现在的原则是:任何会跑在生产环境的工作流,都必须配错误处理。n8n 里最基础的是节点级别的重试设置,你可以配置重试次数和重试间隔。对于调用外部 API 的节点,我一般设三次重试,间隔五秒,这样能扛住大部分临时性的网络抖动。不过重试也不是万能的,如果对方服务彻底挂了,重试一百次也没用,这时候就需要错误工作流出场了。
错误工作流是一个独立的工作流,通过工作流设置里的 Error Workflow 绑定到主工作流上。主流程任何节点报错,错误工作流就会被触发,并且能拿到出错的工作流名、节点名、错误信息这些数据。我用它把所有错误统一收集起来,发到企业微信的错误告警群,同时写进一张数据库表里方便后续分析。这个机制一旦配好,你就再也不用担心流程悄无声息地挂掉了。
执行日志是我调试时最依赖的东西。每次执行都会留下记录,点进去能看到每个节点的输入输出、执行耗时、报错堆栈。我一般会先看哪个节点红了,再看那个节点的输入数据长什么样,八成问题都是数据格式不对导致的。测试策略方面,我的做法是先手动执行跑通,再用测试数据多跑几次,确认各种边界情况都能处理,最后才激活。有些流程我会专门做一个小号环境来测试,避免测试数据污染生产数据。这个习惯养成之后,线上事故少了很多。
2.7 工作流复用与团队协作:模板、凭证、版本管理与权限
工作流做多了之后,复用就变成刚需。n8n 官方有一个模板库,里面有几千个现成的工作流,可以直接导入。我经常去里面找灵感,看看别人是怎么处理某个具体场景的。不过模板不能照搬,里面的凭证、字段名、业务逻辑基本都要改。我自己的做法是把常用逻辑抽成子工作流,比如“发送通知”“写入日志”“调用大模型”这几个,每个主流程都直接调,省得重复搭。
凭证管理是团队协作里最容易出问题的地方。n8n 里的凭证是独立管理的,支持多种类型,也支持 OAuth 授权。团队成员用同一个凭证的时候要注意权限,不然一个人改了 Token,所有人的流程都会受影响。我们的做法是给每个服务创建一个专用账号,凭证用这个账号的信息,谁负责哪个服务就由谁维护。凭证的加密密钥也要保管好,迁移或者备份的时候没有这个密钥,所有凭证都要重新配。
版本管理这块,n8n 本身没有内置 Git 集成,但工作流可以导出成 JSON 文件。我们的做法是把导出的 JSON 放进 Git 仓库,每次改动都提交一次,需要回滚就重新导入旧版本。权限方面,n8n 的企业版有比较完整的用户和角色系统,社区版主要是靠实例隔离。如果团队规模不大,用一个实例加好命名规范就够用。工作流命名我建议带上业务前缀,比如 “crm-” “ops-” “ai-”,找起来会快很多。
2.8 AI 与 LLM 自动化:智能摘要、分类、问答与内容生成工作流
AI 这块是我最近一年投入精力最多的方向。n8n 有专门的 AI 节点,包括 LLM Chain、Agent、Vector Store 这些比较高级的,也可以用 HTTP Request 直接调 OpenAI、Claude、通义千问的接口。我大部分场景用的是后者,因为直接调 API 更灵活,参数和返回都能自己控制。用 AI 节点的时候要注意 Token 消耗,尤其是处理长文本的时候,一次调用可能就花掉几毛钱,工作流跑频繁了成本会很快上来。
智能摘要是最简单的入门场景。我做过一个流程,RSS 里每来一篇新文章,就调用大模型生成一段两百字的中文摘要,连同原文链接一起发到知识管理群里。分类场景也不复杂,把客户留言丢给模型,让它输出“咨询”“投诉”“合作”其中一个标签,再用 IF 节点路由到不同处理人。这两个场景的共同点是输入输出都很规整,调试起来比较容易。问答场景稍微复杂一点,需要搭配向量数据库做检索增强,这块我还在摸索阶段。
内容生成是我觉得最有想象力的方向。我用 n8n 搭过一个流程,输入一个关键词,自动生成一篇结构完整的小红书笔记草稿,包括标题、正文、标签,然后发到飞书文档里人工审一遍。这个流程人工介入的环节很关键,AI 生成的内容直接发出去风险太大,一定要有人把关。我也试过让 AI 自动回复客户咨询,结果发现它有时候会一本正经地胡说八道,后来改成“AI 生成草稿 + 人工确认发送”的模式,效果好很多。AI 自动化的核心不是完全无人化,而是把人从重复劳动里解放出来,专心处理需要判断力的部分。
上一章我们聊完了工作流怎么搭、怎么调试、怎么复用。那些工作流都跑在云版本或者本地的 npx 命令上,说白了一直是“寄人篱下”的状态。执行次数有限、数据不受自己控制、也谈不上什么高可用。这一章我们换个活法,把 n8n 完整地装到自己的服务器上,从一台裸机开始,一步步搭到能扛住生产流量的样子。我会把踩过的坑、绕过的弯都摊开讲。
3.1 自托管部署的价值与选型:Docker、Docker Compose、npm 与云主机
自托管这件事我犹豫了很久才动手。云版本用着确实省心,直到有个月执行次数跑爆了,收到账单那刻我才下定决心。自己部署最大的吸引力是数据留在手里,所有工作流定义、凭证、执行记录都在自己的硬盘上。合规要求高的团队基本只能走这条路,客户数据从第三方服务器过一遍,光想想就睡不着觉。
选型这块我经历了几次反复。npm 直装最简单,npx n8n 或者全局安装都行,适合个人快速验证。这种方式的问题在于环境依赖全压在宿主机上,Node 版本升级、系统库冲突,哪天出问题你会非常被动。我有一台跑了两年的 npn 实例,某次系统更新后直接起不来了,排查了半天发现是 glibc 版本对不上。Docker 把这些麻烦全打包进镜像里,宿主机只需要装一个 Docker 引擎,干净利落。
Docker Compose 是我最终推荐给绝大多数人的方案。它在 Docker 的基础上加了编排能力,把 n8n、数据库、Redis 这些容器的关系、网络、卷全写在一个 YAML 文件里。迁移的时候把这个文件拷过去,docker compose up -d 一条命令就起来了。云主机选择上我没太多讲究,2 核 4G 的入门配置跑单实例完全够用,选离用户近的机房,系统用 Ubuntu 22.04 或 Debian 12 都行。有人问我能不能用家里的 NAS 跑,当然可以,只要网络环境稳定、上行带宽够用,NAS 反而是低成本好选择。
3.2 使用 Docker Compose 快速部署 n8n:镜像、端口、卷与基础配置
第一次写 docker-compose.yml 的时候我对着官方文档抄了一遍,中间漏了个卷映射,结果容器一重启所有工作流全没了,那次教训让我从此对 volumes 格外上心。基础的 Compose 文件其实很短,核心就三块:服务定义、端口映射、卷挂载。镜像用 n8nio/n8n:latest,虽然我后来都锁定具体版本号,latest 某天悄悄更新导致行为变化,这种坑踩过一次就长记性了。
端口默认是 5678,映射到宿主机上也用 5678 就行。如果你打算用反向代理,其实可以只监听 127.0.0.1:5678,外部流量统一从 Nginx 进来,这样更安全。卷这块最关键的是 /home/node/.n8n 这个目录,所有持久化数据都在里面。我习惯把它映射到宿主机的 ./n8n_data 目录,备份的时候直接打包这个目录就行。基础环境变量至少要设 N8N_HOST、N8N_PORT、WEBHOOK_URL 这几个,不然后面 Webhook 回调会因为地址不对而失败。
写完之后执行 docker compose up -d,等十几秒,浏览器打开 IP:5678 就能看到设置界面了。第一次会让你创建 owner 账号,邮箱和密码填好就完事。我建议创建完之后立刻把 N8N_ENCRYPTION_KEY 这个环境变量固定下来,n8n 默认会在首次启动时生成一个密钥存在数据目录里,如果你后期做迁移或者多实例部署,没有这个密钥所有凭证都要重新配。这个密钥是我觉得自托管里最重要也最容易被忽略的一项。
3.3 数据库配置与迁移:SQLite、PostgreSQL 与数据持久化
n8n 默认用 SQLite,开箱即用,不需要额外配置。小规模使用完全没问题,我个人的测试环境跑了半年多,几十个工作流、几万条执行记录,SQLite 扛得住。它的局限在于并发能力弱,多个执行同时写库的时候会出现锁等待。生产环境一旦工作流数量和执行频率上去,SQLite 就会成为瓶颈,这时候必须换 PostgreSQL。
换数据库的过程比我想象的简单。在 docker-compose.yml 里加一个 postgres 服务,把连接信息通过环境变量传给 n8n,DB_TYPE 设为 postgresdb,DB_POSTGRESDB_HOST 填容器名,剩下的端口、用户名、密码、库名填上。启动之后 n8n 会自动建表,不需要你手动跑迁移脚本。这里有个细节,PostgreSQL 的数据也要挂卷,不然容器重建数据同样会丢。我用的是 postgres:15-alpine 这个镜像,体积小、启动快。
从 SQLite 迁移到 PostgreSQL 这件事我做过一次,官方没有现成的迁移工具,得自己导出再导入。我当时的做法是用 n8n 的 CLI 命令导出所有工作流和凭证,然后在新的 PostgreSQL 实例上导入。执行历史我没迁,那些记录对我价值不大,重新开始更干净。凭证的迁移要注意加密密钥必须一致,否则导进去的凭证全是乱码。整个迁移过程花了大概两个小时,主要时间花在验证每个工作流是否还能正常跑。
3.4 域名、反向代理与 HTTPS:Nginx、Caddy、证书与 Webhook 回调
用 IP 加端口访问只能算临时方案。生产环境必须配域名和 HTTPS,原因有两个:一是浏览器对非 HTTPS 的安全限制越来越严,二是很多第三方服务要求 Webhook 回调地址必须是 HTTPS。我第一版用的是 Nginx,配置不算复杂,一个 server 块监听 443,把请求代理到本地的 5678 端口,再加上一段 WebSocket 的 upgrade 配置就行。证书用 certbot 自动申请和续期,三个月一次,配好之后基本不用管。
后来我切到了 Caddy,理由很简单,配置更少。Caddy 能自动申请证书、自动续期,配置文件里只要写一行域名和反代目标,剩下的它自己搞定。对于不想折腾证书的人来说,Caddy 几乎是零心智负担的选择。用 Caddy 的时候要注意,它会占用 80 和 443 端口,如果服务器上已经有 Nginx 在跑,得先把冲突处理掉。
Webhook 回调这块我踩过一个印象深刻的坑。反向代理配好之后,外部服务能访问到我的域名,但 n8n 发出的 Webhook 回调地址还是内网 IP,导致 OAuth 授权一直失败。原因是 WEBHOOK_URL 这个环境变量没设对,n8n 生成回调地址时会读取这个值。正确做法是把它设成你的公网域名,比如 https://n8n.yourdomain.com。这个变量改完之后要重启容器才生效,我当时改完没重启,又白折腾了半小时。
3.5 安全加固与访问控制:加密密钥、认证、用户权限与环境变量
自托管最容易被忽视的就是安全。默认配置下,知道你 IP 和端口的人就能打开登录页,虽然需要密码,但暴露面还是太大了。我做的第一件事是加基础认证,在 Nginx 或 Caddy 层面再加一层 HTTP Basic Auth,这样连登录页都看不到,必须先过一层账号验证。代价是每次访问都要多输一次密码,安全性提升是值得的。
n8n 自身的认证机制值得花时间研究。社区版支持基础的邮箱密码登录,企业版有完整的用户和角色系统。我建议至少开启 N8N_USER_MANAGEMENT_DISABLED=false 这个选项,确保用户管理是开启状态。环境变量里的敏感信息要特别注意,数据库密码、加密密钥这些东西不要写死在 Compose 文件里,用 .env 文件管理,并且把这个文件排除在版本控制之外。我见过有人在 GitHub 上公开了自己的 docker-compose.yml,里面明文写着数据库密码,简直是灾难。
加密密钥这块我要再强调一次。N8N_ENCRYPTION_KEY 一旦设定就不能随便改,改了之后所有已存的凭证都会解密失败。我现在的做法是在密码管理器里存一份,在服务器的安全位置再存一份,双保险。另外,容器内的进程不要用 root 跑,n8n 官方镜像默认用的是 node 用户,这个设置保持默认就好。宿主机层面我还会配一下防火墙,只放行 22、80、443 这三个端口,5678 不对外开放。
3.6 备份、升级与监控:数据备份、版本升级、日志、告警与健康检查
备份这件事我吃过亏,所以现在做得比较认真。核心要备份的是 n8n 的数据目录,里面包含工作流、凭证、执行历史、加密密钥。如果用 PostgreSQL,数据库的备份也要纳入。我的方案是写了一个 shell 脚本,每天凌晨做一次打包,保留最近三十天的备份,同时同步一份到对象存储。脚本很简单,docker compose exec 进容器导出数据库,tar 打包数据目录,scp 传到远程。整套跑下来不超过五分钟。
升级 n8n 我用的是最朴素的方式:改 Compose 文件里的镜像版本号,然后 docker compose pull && docker compose up -d。大版本升级之前我会先看官方的 breaking changes 文档,确认没有影响到我用的节点。升级前一定要备份,这是铁律。有一次我从 0.x 升到 1.x 没备份,结果几个老工作流的节点参数格式变了,花了一个下午手动修复。那次之后我的升级流程里备份永远排在第一步。
监控方面 n8n 自带 /healthz 这个端点,返回 200 就说明服务正常。我用 Uptime Kuma 每分钟探测一次,挂了就发通知到手机。日志方面容器默认输出到 stdout,可以配 Docker 的日志驱动限制大小,避免磁盘被写满。我还配了一个错误告警工作流,前面章节讲过,这里复用就行。执行失败的告警和服务的存活监控是两回事,两个都要有,缺一个都会出现“服务活着但流程全挂”的盲区。
3.7 生产级扩展:队列模式、Redis、Worker 与水平扩展
单实例的 n8n 能扛住的量其实不小,我见过一些团队跑到每天几万次执行也没事。瓶颈通常出现在执行时间长的流程上,一个流程跑十分钟,后面排队的就得等。队列模式就是为解决这个问题设计的。开启之后 n8n 会分成主进程和 worker 进程,主进程负责接收任务,worker 负责执行具体流程,中间用 Redis 做任务队列。我配过一次,执行吞吐量确实有明显提升。
队列模式的配置比单实例复杂一些。Compose 文件里要多加 redis、n8n worker、n8n webhook 这几个服务。EXECUTIONS_MODE 要设成 queue,QUEUE_BULL_REDIS_HOST 指向 redis 容器,主进程和 worker 共享同一个数据库和加密密钥。启动顺序也有讲究,redis 和数据库要先起来,worker 最后起。我第一次配的时候 worker 一直连不上主进程,查了半天发现是 Redis 的密码没对上,这种小细节特别容易漏。
水平扩展就是把 worker 数量从 1 调到 N,每个 worker 都是无状态的,可以随时加随时减。我用 docker compose up -d --scale n8n-worker=3 这条命令扩过。要注意的是扩展之后执行历史会分散在各个 worker 上,查询的时候稍微慢一点,功能上没问题。对于绝大多数中小团队来说,队列模式配两到三个 worker 已经绰绰有余,没必要一上来就搞 Kubernetes 那一套。
3.8 常见故障排查与迁移实践:端口、权限、时区、网络与云平台注意事项
端口冲突是我遇到过频率最高的故障,没有之一。很多时候是 5678 已经被别的服务占用了,n8n 启动直接失败。排查方法很简单,ss -tlnp | grep 5678 看看谁在占。权限问题也很常见,卷映射的目录如果宿主机上的用户 ID 和容器内的 node 用户对不上,n8n 会因为没有写权限而启动异常。我一般的做法是把宿主机目录的 owner 设成 1000:1000,这是官方镜像里 node 用户的默认 ID。
时区问题很隐蔽,一般不会让服务挂掉,但会让你的定时任务在错误的时间触发。N8N 默认用 UTC,国内用户需要设置 GENERIC_TIMEZONE=Asia/Shanghai 和 TZ=Asia/Shanghai 这两个环境变量。我有个朋友一直抱怨他的日报流程每天凌晨四点才发,查了半天就是这个原因。容器启动时候区也是 UTC,配一下 TZ 让日志时间也本地化,排查问题会舒服很多。
云平台迁移这块我做过几次。从阿里云迁到腾讯云,用的就是打包数据目录、导出数据库、在新服务器上重建容器这三步。有个细节很多人会忘,新服务器的公网 IP 变了,WEBHOOK_URL 和 N8N_HOST 都要同步改。DNS 解析的 TTL 设短一点,切之前降到 60 秒,切换的时候影响面会小很多。不同云平台的防火墙策略不太一样,腾讯云的安全组和阿里云的不完全等价,迁移前把端口放行规则核对一遍,能省掉不少“服务起来了但访问不了”的困惑。
自托管这件事没有一劳永逸的配置,环境会变、需求会变、软件会升级。我的经验是保持简单,能用 Docker Compose 搞定的事不要引入更复杂的东西,能用官方镜像的就不要自己构建。等真的遇到瓶颈了再优化也不迟。这套部署方案我用了快两年,中间除了版本升级和偶尔的磁盘清理,基本不用操心。把它跑稳之后你就能把精力放回工作流本身,那才是真正创造价值的地方。