OneUptime 本地开发环境搭建指南:深入解析 docker-compose.dev.yml 与 npm run dev 全流程
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
本篇技术指南面向希望在本机搭建 OneUptime 开源可观测性平台开发环境的开发者。文章以官方《Desarrollo local / Local Development》文档为核心骨架,完整继承其操作步骤,并深入仓库源码(package.json、docker-compose.dev.yml、configure.sh、config.example.env),讲解npm run dev背后每一环节的底层机制,帮助读者理解开发环境与生产环境(docker-compose.md)的差异,掌握调试端口、热更新挂载、按需启动服务等实战技能。
一、前置条件:本地开发需要什么
根据官方文档,本地开发与传统 Docker Compose 部署有一个关键区别:必须使用docker-compose.dev.yml文件,而不是默认的docker-compose.yml。两者差异详见后文第四节。
在开始之前,请确保你的机器满足以下条件:
- Docker 与 Docker Compose:需要 Docker 引擎以及 Compose V2 插件(
docker compose子命令)。从 configure.sh 源码可见,仓库对环境的校验底线为 Docker20.0.0以上、Docker Compose2.12.2以上、Node.js14.0.0以上; - Node.js 与 NPM:
npm run dev本质上是一组 npm scripts 的串联,因此本机必须安装 Node.js 与 NPM。需要注意的是,package.json 中声明的engines.node为>=26.0.0,建议使用较新的 LTS 版本以保证脚本与工具链兼容。
提示:如果你从零开始安装这些工具,可以直接运行仓库根目录的 configure.sh,它会自动检测并安装缺失的 git、curl、Node.js、Docker、Docker Compose 与 gomplate(跨平台模板渲染工具),并完成后续的配置合并与 Dockerfile 生成(详见第三节)。当然,手动安装并执行下文步骤同样可行。
二、完整操作步骤:三分钟拉起开发环境
官方文档给出的本地开发流程非常简洁,完整命令如下:
# 1. 克隆仓库并进入目录 git clone https://gitcode.com/GitHub_Trending/on/oneuptime.git cd oneuptime # 2. 将示例配置复制为本地配置 cp config.example.env config.env # 3. 启动开发环境 npm run dev文档特别强调:由于是开发环境,你无需编辑config.env中的任何值,直接使用默认配置即可启动;当然你也可以按需调整,但这完全是可选项。
执行完npm run dev后,OneUptime 的开发实例会通过内置的 Nginx 网关在http://localhost对外提供服务。首次访问时,需要注册一个新账号来初始化你的实例(这与生产部署行为一致,见 docker-compose.md)。
按需指定启动的服务
npm run dev命令支持通过 npm 配置参数传递服务白名单。例如,只想启动基础设施(Postgres、Valkey、Clickhouse)与应用主服务,可以这样写:
npm run dev --services="postgres valkey clickhouse app"对应地,package.json 中dev脚本末尾的$npm_config_services变量即接收该参数;不传时默认拉起 docker-compose.dev.yml 中定义的全部服务。
三、npm run dev内部到底做了什么
"一行命令"的背后是四个阶段的有序执行。查看 package.json 中dev脚本的定义:
"dev": "npm run config-to-dev && npm run prerun && export $(grep -v '^#' config.env | xargs) && docker compose -f docker-compose.dev.yml up --remove-orphans -d $npm_config_services"我们可以把这条命令拆解为以下流水线:
阶段 1:config-to-dev—— 将环境切换为 development
该阶段执行 Scripts/Install/ReplaceValueInConfig.js,把config.env中的ENVIRONMENT值替换为development。
这一点很关键:config.example.env 中ENVIRONMENT的默认值是production,且注释明确说明其取值域为test | production | development | ci,其中development 专用于本地开发。ENVIRONMENT最终会通过 docker-compose.base.yml 映射为容器内的NODE_ENV,因此该值决定了服务以开发模式(加载开发依赖、开启调试特性)还是生产模式运行。
阶段 2:prerun—— 同步版本并执行环境配置
"prerun": "node ./Scripts/Install/SyncPackageVersions.js && bash configure.sh"SyncPackageVersions.js:同步各子包(App、Common、Probe、Runner 等)的版本号,保证 monorepo 内依赖版本一致;configure.sh:仓库的自检与自举脚本,重点做了四件事:- 环境校验:检查 Docker(要求
>=20.0.0)、Docker Compose(要求>=2.12.2)、Node.js(要求>=14.0.0)是否满足最低版本,缺失时按操作系统(macOS 用 Homebrew,Linux 用 apt/dnf/apk,Alpine 用 apk)自动安装; - 安装 gomplate:这是一个模板渲染工具,用于将仓库中散落的
Dockerfile.tpl模板渲染为实际的Dockerfile; - 合并环境模板:执行 Scripts/Install/MergeEnvTemplate.js,把
config.example.env中新增的配置键合并进你的config.env,而不会覆盖你已自定义的值。该脚本还专门处理了配置键改名场景——例如REDIS_*在 13.0.0 版本后更名为VALKEY_*,当检测到旧键仍存在时会保留旧值,避免默认占位符覆盖真实密钥; - 生成 Dockerfile:遍历仓库中所有
Dockerfile.tpl(App、Probe、Runner、Home、Nginx 等各服务目录下均有),用 gomplate 结合config.env的环境变量渲染出实际构建文件。
- 环境校验:检查 Docker(要求
阶段 3:加载环境变量
export $(grep -v '^#' config.env | xargs)将config.env中所有非注释行导出为当前 shell 的环境变量,供后续docker compose命令做变量替换使用。
阶段 4:启动容器编排
docker compose -f docker-compose.dev.yml up --remove-orphans -d $npm_config_services显式指定-f docker-compose.dev.yml,以-d后台模式拉起容器,并用--remove-orphans清理不属于当前 compose 项目定义的残留容器。
四、docker-compose.dev.yml 深度解读
开发配置文件 docker-compose.dev.yml 与生产使用的 docker-compose.yml 有本质区别:生产环境拉取镜像运行,而开发环境是"源码热挂载 + 本地构建"。其核心设计如下。
1. 基础设施服务与宿主机端口映射
开发文件通过extends继承 docker-compose.base.yml 中定义的基础服务,并额外暴露宿主机端口,方便开发者用本机客户端直接连接:
| 服务 | 容器内端口 | 宿主机端口 | 说明 |
|---|---|---|---|
| valkey | 6379 | 6310 | 缓存与队列(Valkey,Redis 7.2 的 BSD 许可分支) |
| clickhouse | 9000 / 8123 | 9034 / 8189 | 原生 TCP 端口与分析 HTTP 端口 |
| postgres | 5432 | 5400 | 主数据库 |
| test-server | 9229(调试)/ 3800 | 9141 / 3800 | 测试用 API 服务 |
也就是说,你在宿主机上可以用psql -p 5400、clickhouse-client --port 9034、redis-cli -p 6310直接连入开发用的数据组件,非常便于排查数据层问题。
2. 依赖健康检查(depends_on)
文件顶部定义了一个公共锚点:
x-common-depends-on: &common-depends-on postgres: condition: service_healthy valkey: condition: service_healthy clickhouse: condition: service_healthy所有应用服务(app、probe-1、probe-2、runner、test-server、home、ingress)都声明depends_on: <<: *common-depends-on,即只有 Postgres、Valkey、Clickhouse 通过健康检查后才会启动,从编排层面保证了应用启动时依赖已就绪。
3. 源码热挂载(bind mount)
开发模式下,各服务的源码目录以cached模式挂载进容器,宿主机上对代码的修改会即时反映到容器内(配合 nodemon 等工具实现热重载):
app: volumes: - ./App:/usr/src/app:cached - ./Common/Models:/usr/src/Common/Models:cached ...这里有两点值得注意的工程细节:
- node_modules 采用匿名卷遮蔽:每个服务的
volumes中都包含/usr/src/app/node_modules/这样的匿名卷条目,确保使用容器内的 node_modules 而不是宿主机的,避免因宿主平台(如 macOS 的 darwin-arm64)与 Linux 容器二进制不兼容导致崩溃; - Common 目录按子目录精确挂载:注释中明确解释了原因——Docker Desktop for Mac 上整体挂载
./Common并叠加匿名卷的方式不可靠,匿名卷可能被遮蔽从而把宿主平台二进制暴露给 Linux 容器,因此改为逐个挂载Models、UI、Types、Utils、Server等子目录。
4. 调试端口
各服务都预留了 9229 调试端口并映射到宿主机不同端口(app→9232、home→9212、test-server→9141),便于使用 IDE 的 Node.js 远程调试(--inspect)功能附加到容器内进程。
5. 开发专用的日志采集链路
文件末尾定义了fluentd与fluent-bit两个服务。注释说明这些容器仅开发时需要:生产环境由用户自建日志管道将日志送入 OneUptime,而开发环境内置这两个采集器(分别监听 24224 与 24225 端口),用于验证日志是否能正确接入平台。
五、config.env 关键配置说明
虽然开发环境无需修改任何配置即可运行,但了解 config.example.env 中几个与开发强相关的变量仍然很有价值:
| 变量 | 默认值 | 作用 |
|---|---|---|
ENVIRONMENT | production | 运行环境,npm run dev会自动改为development |
HOST | localhost | 实例对外域名,开发时保持 localhost 即可 |
ONEUPTIME_HTTP_PORT | 80 | OneUptime 对外 HTTP 端口 |
COMPOSE_PROJECT_NAME | oneuptime | Docker Compose 项目名,用于给容器命名加前缀 |
LOG_LEVEL | ERROR | 日志级别,调试时可临时改为DEBUG(注意 DEBUG 输出含敏感信息,用完请关闭) |
DISABLE_TELEMETRY_* | true | 开发时默认关闭各服务自身的遥测上报 |
开发时最常用到的是LOG_LEVEL:把config.env中的LOG_LEVEL=DEBUG后重启相关服务,即可看到更详细的调试日志。除此之外,文件底部还有大量可选配置(AI LLM Provider、Slack 集成、GitHub App、推送通知等),本地开发时保持默认即可,需要联调对应功能时再按需填写。
六、日常开发常用命令
除了npm run dev,package.json 中还提供了一批配套脚本,覆盖开发全周期:
# 查看当前运行的容器 npm run ps # 查看最近 100 行日志(支持 --services 指定服务) npm run logs --services="app" npm run follow-logs --services="probe-1" # 实时跟踪日志 # 停止并移除容器(不会删除 config.env 与仓库) npm run down # 等价于 npm run stop # 重新构建开发镜像 npm run build --services="app" npm run force-build-dev # 先切到 development 环境,再 --no-cache 全量重建 # 一键安装/清理各子包依赖 npm run install-modules npm run clean-modules其中install-modules会遍历仓库根目录下每个子目录执行npm install(见 Scripts/Dev/install-node-modules.sh),用于首次拉取代码后补齐各服务依赖。
七、本地开发与生产部署的差异
理解开发环境的设计,最好的参照是官方生产部署文档 docker-compose.md。两者的核心差异可归纳为:
| 维度 | 本地开发(docker-compose.dev.yml) | 生产部署(docker-compose.yml) |
|---|---|---|
| 启动命令 | npm run dev | npm start |
| 镜像来源 | 本地源码构建(bind mount 热挂载) | 从镜像仓库拉取 release 标签镜像 |
| 配置要求 | 无需修改 config.env | 必须替换所有默认密钥(ONEUPTIME_SECRET、DATABASE_PASSWORD、CLICKHOUSE_PASSWORD、VALKEY_PASSWORD、ENCRYPTION_SECRET等) |
| 端口暴露 | 数据组件端口暴露到宿主机便于调试 | 仅对外暴露 HTTP/HTTPS 端口 |
| 日志采集 | 内置 fluentd/fluent-bit 验证链路 | 需自行配置日志管道并限制日志存储量 |
生产文档还特别提示:官方强烈建议生产环境优先使用 Kubernetes + Helm Chart 部署,docker-compose 更适合自托管单机场景;并且生产环境需要自行通过反向代理(Nginx/Caddy)与 Let's Encrypt 配置 TLS,同时在config.env中把HTTP_PROTOCOL改为https、把HOST改为反向代理的域名。
八、常见问题排查思路
结合上述源码机制,可以快速定位本地开发中的典型问题:
- 端口占用导致启动失败:
ONEUPTIME_HTTP_PORT=80以及 6310/9034/5400 等映射端口可能与本机服务冲突,可在config.env中调整对应端口,或在npm run dev后通过npm run ps检查失败的服务; - 代码修改未生效:确认服务以
cached挂载且容器内运行的是开发模式(ENVIRONMENT=development),并检查是否缺少宿主机不具备但容器需要的原生依赖——这正是 node_modules 必须使用容器内版本的原因; - 环境变量不生效:
dev脚本通过grep -v '^#'过滤注释行后加载配置,修改config.env后需要重启相关容器;若新增了config.example.env中不存在的键,MergeEnvTemplate.js不会自动补全,需手动添加; - 构建缓慢:首次
npm run dev需要对所有服务执行 Docker build,可使用npm run build --services="app"定向构建,或调整--services参数只启动当前开发所需的服务组合。
至此,你已经掌握了 OneUptime 本地开发环境从启动命令到底层机制的全貌:一条npm run dev背后是环境切换、版本同步、模板渲染、配置合并与容器编排的完整流水线,而docker-compose.dev.yml的"源码热挂载 + 健康检查 + 调试端口"设计则为高频迭代开发提供了最大便利。后续可继续阅读仓库内 CLI 文档 与 监控器配置文档,从"跑起来"迈向"深入二次开发"。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考