在群晖部署 n8n 的一些坑和经验

n8n 是一个开源的低代码平台,能够让你在不写一行代码的情况下,完成自动化程序。我之前在做明日故乡利用AI打造阅读系统的时候都有尝试过。

最近一年,随着大模型的流行,n8n 也越来越火,毕竟这是最方便、最低成本让普通人可以打造自己 AI 工具(而不是使用别人的工具)的方法。

我的 n8n 此前一直是在群晖上部署的,这样意味着一年可以少一份订阅式的费用,还不用担心存储的问题。当然最主要的,还是觉得群晖的 CPU 日常限制着,有些浪费。

但在实际使用过程中,在群晖上使用 n8n 还是存在问题的。

先说结论:建议别搞,不如用我的链接去 CloudCone 上买个服务器,才 400 一年。

但你一定要搞,本文是一些我踩过的坑。本文不是一个部署教程,因为某种程度上 n8n 的适应性很高,在群晖上属于一键部署。你只要会用群晖上的 Docker,直接搜 n8n 建容器就行。

第一坑:Editor 无响应

这是一个很奇怪的 bug,它的状况是这样的,你在 n8n 的 Editor 里运行了一个 Workflow,但它没有实时显示出运行到了哪个 node。并且此时,你点击 Stop,它也不会停止。但当你再次停止的时候,会发现它提示无法停止一个已经停止的 Workflow。

然而,当你进入 Executions 查看运行记录的时候,你会发现 Workflow 一开始其实是正常运行了,当你点了 Stop,其实也会正常停止。这意味着,这个 BUG 实际不会影响 Workflow 的运作,最大的影响是你在编制 Workflow 的过程中,调试会变得非常麻烦。尤其是因为没有办法看到执行结果,你也就没法以拖拽的形式从上一个 Node 输出的变量拖到下一个 Node。这简直是让 n8n 作为可视化 lowcode 的作用减半。

我在网上搜索了很久,在 n8n 的 Github 里有一个相关 Issue,但因为环境与我不同,因此并没有给我太大的帮助。

真正的解决方法:不要使用群晖 Web Station 作为网页门户让 n8n 进行外部访问。

使用 控制面板>登录门户>高级>反向代理服务器 这里的反向代理来配置 n8n 的外部访问。配置十分简单:

但到此为止,问题仍然没有解决,因为实际上这个问题是 n8n 前端无法通过 WebSocket 与后端沟通导致的。因此,需要继续点击上面的“自定义标题”。然后选择 新增 > WebSocket

它会默认增加两个方法的代理,一个是 Upgrade 一个是 Conncection,直接保存就行。如果以后的 DSM 版本没有自动填入,那么你手动填入以下就可以:

标题名称
Upgrade$http_upgrade
Connection$connection_upgrade

至此为止,大功告成。你的 n8n Editor 应该已经可以正常响应运行状态了。

这个方法其实并不是我原创的,而是根据这篇英文的教程推导出来的。

这篇英文的教程原本写的是如何在群晖上安装 n8n,但其实你不用 follow 那个教程,因为它单独在群晖上安装了一个第三方 Docker 管理器 Portainer,这个是没必要的。如果你在群晖上还没部署,其实直接在 DSM 7.0 以上的自带 Container Manager 里直接搜 n8n 安装就能用了。

环境变量设置上,可以参考我的:

备注
N8N_Prot 5678 Docker端口
N8N_PROTOCOLhttps开启 https 访问
N8N_HOST你的名字.familyds.net你用于外网访问的DDNS,不带端口,如不想从外网访问可以不设。
N8N_WEBHOOKhttps://你的名字.familyds.net:5680/n8n 用于接 Web hook 的地址,和你从外网访问 n8n 的地址是一个,要带协议头。
GENERIC_TIMEZONEAsia/Shanghai设置 n8n 的默认时区

另外,就是要设置一下永久化存储:

在群晖中找一个目录,把它映射到 n8n Docker 的 /home/node/.n8n/ 里。否则的话,你的 n8n 虽然可以正常运行,但你下次用 Docker 升级 n8n 版本的时候,你的数据和 workflow 就全都被清空了。

第二坑:外网访问

这个其实不算坑啦,就是有些人可能比较困惑,到底怎么设置端口才能让外网访问到群晖上的 n8n。

这里就简单讲一下。

首先,你的群晖本身要能被外网访问,这里有几个先决条件:

  1. 如果是家庭宽带,你首先要有公网 IP,这个需要打电信或联通的客服来获得,网上有教程自己搜。
  2. 控制面板>外部访问>DDNS 中新增一个 DDNS,为了方便,你可以直接用群晖的。
  3. 让群晖出现在公网上,这里有两种选择:
    • UPnP(推荐):控制面板 > 外部访问 > 路由器配置 里开启 UPnP。
    • DMZ:在路由器中直接设置 DMZ 为群晖的内网 IP。

我不推荐 DMZ 的原因是我不放心群晖的安全性,使用 UPnP 能更好的控制群晖的哪些端口可以被外网访问。

那在选择 UPnP 的情况下,IP 设置就会有些拧巴。

首先,我们上面的环境变量里设置了 N8N 为 5678,这是 Docker 端口(容器端口)。但 Docker 一般与主机之间采用桥接网络,这意味着你还有一个本地端口。最后,为了让外部访问,你还需要有一个外部端口

网络链路实际上是这样的:

N8N ➡️ 群晖本地 ➡️ 路由器(外网)

在使用群晖的 Docker 安装 n8n 的过程中,如果你不小心勾选了用 Web Station 代理 n8n 那么你会在 n8n 的项目设置里发现 5678 这个端口已经被永久占用了:

不过没关系,你只要新增一个端口转发,在容器端口处填写 5679,然后在本地端口填入 5679 就行了。如果你用了非默认的容器端口,那么就需要参照我上面的环境变量设置将其修改为你实际的容器端口。

本地端口可以和容器端口不一致。

这样设置完成之后,进入 控制面板>登录门户>高级>反向代理服务器,按照我在坑 1 的截图里那样设置。来源是你的 DDNS 地址,端口是你未来想实际访问 n8n 时的端口,也就是外部端口。目的地是 localhost,端口是本地端口

最后,控制面板 > 外部访问 > 路由器配置 里设置 UPnP。在这里,你应该可以选择新增 内置应用程序,然后直接选择已经建立好的 n8n 反向代理。

第三坑:连接大模型

这个是最坑的,如果你的群晖放在大陆,并且希望 n8n 连接大模型,我劝你从这里开始打消念头。因为首先,群晖本身上真网就比较困难。

但当你废了九牛二虎之力给群晖搞上真网之后,却发现 n8n 里不起作用。哪怕你设置了 HTTP_PROXY 和 HTTPS_PROXY,n8n 的某些节点依然不能访问那些不该访问的网站。

简单来说,n8n 的部分节点,使用了一个名为 Axios 的库发起网络请求。而这个库有一个长达 4 年的问题,就是它无法通过 HTTP 协议代理 HTTPS 链接。它要求,你填写在 HTTPS_PROXY 的那个地址,必须是一个带有证书的 https 地址,而不是小猫咪的本地 IP 地址。这意味着中国人熟悉的那些透明代理,全都不能用。

Axios 库本身有一些打补丁的方法来解决这个问题,但被打包在 n8n 里的 Axios 不能解决这个问题。

有三个临时解决方案:

  1. 使用一个旁路由,实现群晖物理上游的全屋真网。
  2. 在 Workflow 的设置中,将 Execution Order 改为 v0(legacy)。
  3. 使用 HTTP Request 节点来代替 LLM 节点,直接向大模型发起请求。

这三种方法只有第一种是完美的,但大部分人可能没法实现这个方案。

第二个方法的问题是,有些节点即便是在 v0(legacy) 下也会无视环境变量中的代理设置,比如 RSS Read 和 RSS Feed Triger。而且,这个是 n8n 在 1.0 版本之前的执行库,指不定哪天就下了。

第三个方法的问题是,n8n 的 AI Agent node 不能连接 HTTP Request,这意味着你不能用它来做包含 Chatbot 或 LangChain 的 Workflow。

所以,其实在群晖上部署 n8n 坑还是蛮多的。你真的想要用 n8n 连接大模型嵌入自己日常的工作流,那你还是可以考虑在国外买个服务器来完成这件事,一年也就 400 块钱左右。

CloudCone 目前刚刚开启了 2024 年的促销 4CPU\4GB\220GB 的机器一年只要 55.9 刀,如果你感兴趣,可以通过这个链接去看看,会给我返利。除了这个机型之外,还有更便宜的可以选择,跑 n8n 绰绰有余:

如果你有其他 n8n 使用上的问题,也可以在这篇下面留言,我知道的尽量回复。

评论尸 的头像

如果你觉得本文有信息增量,请:

喜欢作者

 

精选评论

  1. Reed 的头像

    在zeabur上部署就行,非常方便。用的少一个月5美刀免费已经够用。付费的话一个月5美刀到部分情况已经可以覆盖。

    1. 评论尸 的头像

      Zeabur 比单租 VPS 贵了,VPS 的话还能闲时跑跑别的服务,比如如果你用 n8n 做 AI,那负责长期记忆的 Motohead 是不是也要整一下。

  2. CzBiX 的头像

    外网访问这部分,我的建议是用Tailscale这类P2P VPN。既不需要公网IP,也起到了安全防护的作用。

    1. 评论尸 的头像

      外网访问的需求不只是我自己访问,还有要让外部服务能访问 n8n 的 Webhook,所以把 n8n 彻底暴露出去是必然的。
      安全方面的话,放通了外网,建议开启两步验证。

  3. H2116 的头像

    最近也刚好部署了n8n,自动拉取RSS的一些图片到本地,方便查看。刚好碰到网络代理问题,用HTTP节点支持代理,然后自行ExtraXML的方式替换RSS节点,相对麻烦了一些。
    另外还遇到一个Bug十分痛苦,做了3个RSS节点,后面分别分析出每一个RSS的列表,并使用For节点进行一些处理,结果会只执行第1个RSS节点的所有列表,后续的不会执行。
    最后通过单独实现一个处理列表的子workflow,另一个workflow分别单独的节点去调用子workflow。
    (想念jenkins了,懂点python或者直接用GPT生成Python代码来使用,更省心。)

    1. 评论尸 的头像

      最新版的 n8n Code 节点支持 Python了。然后 RSS 节点本地化的问题,我是通过另外开了个 FreshRSS 做反向代理的,就是所有不过代理访问不了的 Feed,先过一遍本地的 FreshRSS ,再让 n8n 读取。

  4. SurfRid3r 的头像

    如果是Docker部署的n8n,我之前也碰到了http_proxy网络代理的问题,最后是通过在宿主机上修改iptables+redsocks将流量重定向转发给代理

    1. 评论尸 的头像

      我看了下教程,太复杂了,我怕我手生把群晖搞崩了。因为我群晖确实还是在当 NAS 用的,里面有些数据。

  5. joojenZhou 的头像

    为啥大家都选择群晖

    1. 评论尸 的头像

      因为群晖的全球社区真的活跃,想干啥网上一搜都有人尝试过了。

  6. Macin 的头像

    在谷歌云上买了个服务器,然后使用一个软路由,实现群晖物理上游的全屋真网。
    现在的问题是 docker 又用不了,真的是….

    1. 评论尸 的头像

      你都买服务器了,我的建议是不要用 n8n 折磨群晖了。