And why we replaced n8n with Laravel along the way
当我们开始构建内部自动化平台时,我们以为自己选对了技术栈。我们用 n8n 进行工作流编排,用 Semaphore UI 运行 Ansible playbook,并对如何全面自动化托管运营有一套设想。几个月后,我面对的只能用一张蜘蛛网来形容——我知道我们必须从头再来。
我是 Savvii 的 CTO,这是一家位于荷兰的托管托管服务公司。我们专注于基于 PHP 的网站——电子商务、WordPress 及类似工作负载——并服务于三类客户:小型客户、分销商和代理商。每一类都有不同的需求、不同的规模和不同的期望。
代理商这一客户群是我们感受到压力最大的地方。代理商是成熟的客户,但他们的内部团队往往是技术与非技术人员的混合体。他们需要一个图形界面。他们无法靠命令行生存。我们接入的代理商越多,一件事就越发明显: 我们需要一个由真正的自动化支撑的合适的控制面板。
Ansible Tower 及类似工具曾在我们的考量范围内,但它们要么设置过于复杂,要么文档不一致,要么带有性能和数据主权方面的顾虑。 我们想要一个可以自托管、升级时不会带来麻烦的东西, 并且能够移交给我们的支持团队,而无需一周的培训。
在做出任何决定之前,我们进行了一次全面的比较。有两个因素很快缩小了选择范围。
数据主权。 不接受任何会把状态或凭证存储在第三方云中的工具。自托管是不可妥协的。
面向非工程师的用户体验。 一线支持团队是优秀的沟通者,而非系统管理员。无论我们选择什么,都必须能够在不把每个事件升级给 DevOps 的情况下使用。我们评估的工具包括:
| 评判标准 | Semaphore UI | n8n | AWX / Tower | Rundeck |
|---|---|---|---|---|
| 默认自托管 | 是——单一二进制文件 / 熟悉的部署方式 | 是——自托管版本 | 是(AWX)/ 混合(AAP 云选项) | 是 |
| 一线支持的用户体验 | 任务&清单清晰度强 | 适合编写者;运维移交较弱 | RBAC 概念繁重;对支持团队上手困难 | 以作业为中心;Ansible 使用体验较差 |
| Ansible 清单&执行的用户体验 | 围绕项目&模板构建 | 不是 Ansible 控制平面 | 原生但升级路径复杂 | 可行;并非以 Ansible 为先 |
| 用于自定义中间件的 API | 一致的任务&项目 API | 功能广泛;运营模型不同 | Tower API 表面随版本而异 | 成熟的作业 API;原语不同 |
| 升级&运营负担 | 实践中升级摩擦低 | 取决于工作流的蔓延程度 | 通常较重(K8s / 捆绑依赖) | 中等;JVM 占用 |
Semaphore UI 在这两方面都胜出。安装很简单。升级毫无痛苦。界面足够清晰,连非工程师都能理解正在发生什么。接入我们现有的 Ansible 清单几乎没有摩擦——唯一需要帮助的地方是连接清单,而这通过支持团队很快得到了解决。Semaphore 的文档很扎实,这给了我们信心。
最初的架构使用 n8n 作为 HostBill(计费)、Semaphore UI 和 CMDB 之间的编排层。在纸面上看起来很干净——低代码、可视化,无需开发人员维护。
n8n 的可视化界面对于简单的线性流程非常出色。但一旦条件判断、错误处理、多步回调和状态管理进入画面——全局视图就消失了。原本干净的图示变成了一块超现实主义的电路板。
没有安全的状态存储
在我们使用的版本中,没有安全的方式在步骤之间存储中间状态。
安全方面的顾虑
日志中没有可靠的密码掩码——当 Ansible 回调包含生成的凭证时,这是一个严重的问题。
脆弱的回调
n8n、Semaphore 和 CMDB 之间的回调处理需要过多的来回交互,这使得流程变得脆弱。
我们用一个 Laravel 应用替换了 n8n。它是真正的中间件——不是无代码工具,而是我们团队完全拥有并理解的东西。
安全模型
每台服务器都有一个 authorized_keys 文件,用于限制 Semaphore 的 SSH 密钥实际能做什么。通过使用 authorized_keys 中的 command 指令,我们精确定义了 Semaphore 被允许运行哪些命令。在初始设置之后,Semaphore 还会失去 root 访问权限——它只能连接到用户账户。
这显著限制了万一发生任何泄露时的影响范围。
我们起步的代理商客户群,通过这套架构运行着约 600 台服务器。三类客户群的总体规模最终将达到 3,000 到 4,000 台服务器,我们正在逐步推广这一平台。
Semaphore 的调度器是下一个要上线的功能,用于服务器更新——目前由外部工具处理,但将转向由调度器驱动的 Ansible。
支持团队的独立性
支持团队可以独立使用 Semaphore,而无需在每个事件中拉上 DevOps。
实时告警
Slack 集成在 playbook 失败时为工程团队提供即时告警。
整洁的模板
通过 API 传递变量,使模板数量保持较低——避免了蔓延。
准确的 CMDB
CMDB 会自动保持准确——不再需要手动维护。
我们会做出的最大改变是: 在写下一行自动化代码之前,花更多时间进行架构设计。 我们不止一次从头再来,因为我们没有足够仔细地思考哪些流程能够扩展,以及哪些流程能够优雅地处理失败。
架构优先
在写下一行自动化代码之前,花更多时间进行架构设计。仔细思考哪些流程能够扩展并优雅地处理失败。
以用户体验评估,而不仅仅是功能
如果你的支持团队在凌晨两点不打电话给资深工程师就无法使用它,那它就是错误的工具。
数据主权很重要
在进入生产环境之前,先弄清楚你的凭证和状态存放在哪里。
好的文档是一个信号
如果一个工具的文档一团糟,那这个工具很可能也是如此。
Start with OSS, upgrade to Pro when your team grows. Enterprise support and SLA are available — including for hosting providers running thousands of servers.