文章 /

condev-monitor 项目部署问题

复杂监控系统部署方案选择与排错过程

condev-monitor 是一整套前端监控链路。部署需要考虑数据库、SDK 接收端、Dashboard 前后端和邮件告警等方面。以下为实践方案选择

  • Coolify + docker-compose 部署过程网络反复被 prune
  • pm2 + docker-compose 混合部署运行方式割裂
  • 2C2G 机器加 swap 后依然 OOM
  • argon2nest-modules/mailer 在目标环境下维护成本过高而选择其他包

一、部署约束

这个项目主要包含几部分:

  • 监控错误与性能的 SDK
  • 用于测试 SDK 接入的 examples/vanilla
  • 接收上报数据的 dsn-server
  • Dashboard 前端 frontend/monitor
  • Dashboard 后端 backend/monitor

开发环境里,数据库依赖 ClickHousePostgres 两个 Docker 镜像,其他部分通过 pnpm start:devpnpm dev 本地运行。线上部署时简化流程,把多服务链路稳定收敛成一种运行方式比较重要。

二、放弃 Coolify

一开始计划在 Coolify 上用 docker-compose 部署。实际尝试多次后,部署过程中 network 会被 Coolify 内部 prune 掉,并伴随多种异常。

更大的问题是平台层和业务栈可能互相打架:项目里的 caddy 与 Coolify 自身依赖的 caddy 可能存在冲突。只要平台抽象本身已经干扰 Compose 栈,就不应继续把时间花在修平台兼容性上。而且如果去掉项目开发环境使用的 caddy 镜像,后续其他人使用无法简易部署。而且项目后续需要改写为微服务架构,保留用于反向代理的镜像。

对于多容器、双数据库、带代理层、未来考虑微服务架构、用户部署简单等问题,保证部署简易

三、收敛为全量 docker-compose

项目曾考虑和尝试过几种运行方式:

  1. Next.js 走 OpenNext 适配器,部署到 Cloudflare,NestJS 后端走企业内网主机,通过 Tunnel 暴露。这样后端崩掉,前端页面托管在 Cloudflare 也能打开。
  2. 或者前后端都放在企业内网主机上,用 docker-compose 管理,这样方便简易部署
  3. 或者服务器上用 pm2 跑部分服务,数据库仍走容器,比较麻烦

这些组合方式的问题:运行方式分裂后,部署和排障成本会上升。尤其是 NestJS 后端不能直接去掉 node_modules 部署,OpenNext 项目用 pm2 也出现错误,最终让混合部署变得越来越重。

后面直接收敛:服务尽量统一放进 docker-compose。先保证启动方式、依赖和环境变量入口一致,再谈更细的拆分。

四、依赖和资源问题

1) 国内机器碰壁

手里正好有一台国内的阿里云 2C2G + AliLinux 机器,但是在配置了 swap 并在全量 Docker 部署下频繁 OOM。

后续想过只容器化 ClickHousePostgres,其余服务由 pm2 跑起来,但步骤过于繁琐,最终还是放弃。机器资源不够时,先换更合适的实例,往往比继续做运行时拼装更直接。

2) 不稳定依赖

在将服务打包成 compose 的时候, Dashboard中的 NestJS 后端里,argon2 在阿里云服务器默认 Python 3.6 环境下编译失败,切到 Python 3.7 后仍然报错。会持续放大部署成本的依赖问题,后面直接改成了 bcryptjs

另一个问题是较旧的 nest-modules/mailer。在 Docker Compose 部署中,它会报 CSS-in-JS 相关依赖缺失。虽然 GitHub issues 中有解决方案,但不够标准和自动化,维护成本也高,最后改为 nodemailer

3) 邮件发送要降级

迁移到 Netcup 4C8G 机器后,全量镜像可以正常部署,但在测试时发现服务器不支持 SMTP 发信。于是邮件发送链路改成:

  1. 优先使用 Resend 的 HTTP 服务发信
  2. HTTP 发信异常时,再回退到原有 SMTP 方案

这样做的目的保证严重错误发生时,告警链路仍能尽量可用。而且 Resend 的 HTTP 方案和 Cloudflare 只支持接收邮件而不支持发送邮件做了互补。

五、最终取舍

最后采用的是外网 Netcup 4C8G 机器 + 全量 docker-compose。这样避开了备案和平台兼容问题,也让后续其他 AI 项目的部署环境更统一。保留 openNext 的 Cloudlfare 部署,未来看使用者需求去选择使用 Tunnel 分开部署前后端。