Rivet 多节点开发环境搭建指南:dev-multinode Docker Compose 模板深度解析
【免费下载链接】actorsRivet Actors are the primitive for stateful workloads. Built for AI agents, collaborative apps, and durable execution.项目地址: https://gitcode.com/GitHub_Trending/riv/actors
Rivet 在仓库中通过自动生成的 Docker Compose 模板提供了一套完整的自托管开发环境,其中dev-multinode是专为多节点拓扑设计的模板:在单个数据中心(datacenter)内拉起 3 个 Rivet Engine 节点与 3 个 Runner 节点,并配套 ClickHouse、PostgreSQL、NATS、Vector、OpenTelemetry Collector、Prometheus 与 Grafana 等完整基础设施。阅读本文后,你将能够理解该模板的生成机制与目录结构、掌握一键启动/停止/排障的常用命令、读懂三节点 Engine 与 Runner 的配置文件,并弄清楚日志与指标从产生到落库的完整链路。
模板概览:一次拉起一个完整的 Rivet 多节点开发集群
dev-multinode是位于 self-host/compose/dev-multinode/ 的自动生成模板。目录头部明确标注了其性质:Auto-generated,即该目录及其中所有文件均由模板生成器自动产出,不应直接手工编辑,否则修改会在下次生成时被覆盖。
该 Compose 配置为 Rivet 提供了完整的开发环境,包含以下服务:
| 服务 | 角色说明 |
|---|---|
| Rivet Engine | 核心编排服务(本模板启动 3 个实例) |
| Rivet Shell | 交互式调试 Shell(常驻容器) |
| Runner | 执行用户代码的运行时(本模板启动 3 个实例) |
| ClickHouse | 分析型与时序数据库(日志、追踪的落库目标) |
| PostgreSQL | 关系型数据库(Rivet Engine 的主存储) |
| Vector Server | 日志聚合与处理(汇总各客户端日志) |
| OpenTelemetry Collector | 可观测性数据采集(OTLP 与 Prometheus 抓取) |
从模板定义看(见 self-host/compose/template/src/config.ts),dev-multinode的核心拓扑参数为:
- 网络模式(networkMode):
bridge - 数据中心(datacenters):1 个,名为
default,id 为1 - Engine 数量:
3 - Runner 数量:
3
值得注意的是,README 中标注的生成器路径为docker/template/,而当前仓库中实际对应的生成器源码位于 self-host/compose/template/,其中src/config.ts同时定义了dev、dev-multinode、dev-multidc、dev-multidc-multinode、dev-host等多个模板,dev-multinode正是单数据中心多节点的代表。
端口配置总览
模板对外暴露的端口如下,这是联调本地客户端、访问可观测性面板时的关键参照:
| 服务 | 端口 | 说明 |
|---|---|---|
| Rivet Engine | 6420 | 公共端点(HTTP API) |
| Runner | 5050 | 代码执行服务 |
| PostgreSQL | 5432 | 数据库 |
| ClickHouse HTTP | 9300 | 数据库 HTTP 接口 |
| ClickHouse Native | 9301 | 数据库原生协议端口 |
| OpenTelemetry gRPC | 4317 | OTLP gRPC 端点 |
| OpenTelemetry HTTP | 4318 | OTLP HTTP 端点 |
除表格列出的端口外,从 docker-compose.yml 还可以看到更多对外端口:NATS 客户端端口4222、Prometheus 面板9090:9090、Grafana 面板3100:3000。Engine 之间使用的 peer 端口6421与 Prometheus 指标抓取端口6430仅暴露在容器网络内部,不映射到宿主机。
模板配置核心参数
Template Name:dev-multinode
Base Port:6420(Engine 公共端点以此为基础)
Network Mode:bridge
Datacenters:
- 1:3 个 engine(s) + 3 个 runner(s)
在生成器源码 self-host/compose/template/src/config.ts 中,TEMPLATES["dev-multinode"]的Datacenter结构为:
{ name: "default", id: 1, // u16 数据中心编号 peer_id: 1, // u64 peer 编号 engines: 3, // Engine 实例数 runners: 3, // Runner 实例数 }networkMode支持bridge与host两种取值,dev-multinode使用bridge:各服务通过 Compose 创建的自定义网络互相通信,Engine 的valid_hosts中同时包含容器名与127.0.0.1/localhost,兼顾容器内服务发现与宿主机直连两种场景。
快速启动指南
模板根目录提供了一整套开箱即用的操作命令(以下命令均在 self-host/compose/dev-multinode 目录下执行):
- 启动全部服务:
docker-compose up -d首次启动会构建
rivet-engine-*、runner-*与rivet-shell镜像(build.context指向仓库根目录../..,Dockerfile 为 docker/engine/Dockerfile 与 examples/kitchen-sink/Dockerfile),耗时较长属正常现象。
- 检查服务健康状态:
docker-compose ps- 查看指定服务的日志:
docker-compose logs -f [service-name]例如跟踪 Engine 的启动日志:docker-compose logs -f rivet-engine-0。
- 停止全部服务:
docker-compose down由于多个服务配置了healthcheck(Engine 每 2 秒探测一次/health、PostgreSQL 使用pg_isready、NATS 探测8222/healthz),启动后建议稍等片刻再执行docker-compose ps,待所有服务进入 healthy 状态。docker-compose down默认会保留具名卷(clickhouse-data、postgres-data等),如需连数据一并清理可追加-v。
生成的目录结构与文件解析
模板生成以下文件与目录:
dev-multinode/ ├── docker-compose.yml # 主 Compose 配置 ├── README.md # 本说明文件 ├── core/ # 跨数据中心共享的核心服务 │ ├── clickhouse/ # ClickHouse 配置与初始化 │ ├── vector-server/ # Vector 聚合器配置 │ └── otel-collector-server/ # OpenTelemetry Collector 服务端配置 ├── datacenters/ # 数据中心专属配置 │ └── 1/ # 数据中心 1 的配置 │ ├── postgres/ # PostgreSQL 初始化脚本 │ ├── rivet-engine/ # Rivet Engine 配置 │ ├── vector-client/ # Vector 客户端配置 │ └── otel-collector-client/ # OpenTelemetry Collector 客户端配置 └── ...实际生成产物与 README 描述略有出入:当前目录结构中,ClickHouse、Vector Server、OTel Collector、Prometheus、Grafana 等核心配置直接平铺在dev-multinode/根下(如clickhouse/、vector-server/、otel-collector/、prometheus/、grafana/),Engine 的三份配置位于rivet-engine/0、rivet-engine/1、rivet-engine/2三个子目录,PostgreSQL 初始化脚本位于postgres/init-db.sh。以实际目录为准即可,核心思想不变:核心服务配置全局共享一份,Engine 等节点级配置按实例编号各占一份。
深入 Compose:服务拓扑与关键配置项
Rivet Engine(三节点)
rivet-engine-0、rivet-engine-1、rivet-engine-2使用同一镜像构建:
build: context: ../.. dockerfile: docker/engine/Dockerfile target: engine-full args: BUILD_FRONTEND: 'true' platform: linux/amd64关键点:
- 仅
rivet-engine-0映射宿主机端口6420:6420,其余两个节点不暴露端口,通过 Compose 内部网络互通; - 三个节点都配置了健康检查:
curl -f http://127.0.0.1:6420/health,间隔 2 秒、start_period: 30s(给足镜像内前端构建与启动时间); - 环境变量开启链路追踪上报:
RIVET_OTEL_ENABLED=1、RIVET_OTEL_SAMPLER_RATIO=1(全量采样)、RIVET_OTEL_GRPC_ENDPOINT=http://otel-collector:4317; - 各自挂载独立的配置:
./rivet-engine/0|1|2/config.jsonc:/etc/rivet/config.jsonc:ro。
Runner(三节点)与 Runner 注册
runner-0/1/2基于 examples/kitchen-sink/Dockerfile 构建(NODE_IMAGE: node:22-trixie-slim),以serverful 模式运行用户代码:
environment: - RIVET_KITCHEN_SINK_MODE=serverful - RIVET_ENDPOINT=http://rivet-engine-0:6420 - RIVET_TOKEN=dev - RIVET_NAMESPACE=default - RIVET_POOL=default - PORT=8080- 仅
runner-0暴露5050:8080; RIVET_ENDPOINT指向 Engine 0 的公共端点,RIVET_TOKEN=dev与 Engine 配置中的auth.admin_token一致,RIVET_POOL=default对应默认计算池;- Runner 必须等待
runner-config-init成功执行完毕后才会启动。
runner-config-init是一个一次性初始化容器(restart: 'no'),负责向 Engine 注册默认 Runner 配置:
curl -fsS -X PUT "http://rivet-engine-0:6420/runner-configs/default?namespace=default" \ -H "Authorization: Bearer dev" -H "Content-Type: application/json" \ -d '{"datacenters":{"default":{"normal":{}}}}'它会轮询直到 Engine 接受该配置(失败则每 2 秒重试并打印waiting for engine to accept runner config)。这正是「Runner 就绪前必须先有可用的 runner-config」这一依赖关系的实现方式。
Rivet Shell
rivet-shell同样基于engine-full镜像构建,entrypoint: sleep+command: infinity使其保持常驻,作为调试 Shell 挂载了rivet-engine/0/config.jsonc,可通过docker-compose exec rivet-shell <command>进入容器内执行 Engine 相关调试命令。
基础依赖服务
| 服务 | 镜像 | 要点 |
|---|---|---|
| PostgreSQL | postgres:18-alpine | max_connections=500;POSTGRES_USER/PASSWORD/DB均为postgres;挂载 postgres/init-db.sh 初始化脚本 |
| ClickHouse | clickhouse/clickhouse-server:25.1.5 | CLICKHOUSE_HTTP_PORT=9300、CLICKHOUSE_TCP_PORT=9301;挂载 clickhouse/init/01-create-otel-table.sql 等初始化脚本 |
| NATS | nats:2.10.22-alpine | 消息总线,4222:4222,-m 8222开启监控端口供健康检查 |
| Vector Server / Client | timberio/vector:0.48.0-distroless-static | 日志聚合,见下文 |
| OTel Collector | otel/opentelemetry-collector-contrib:latest | 4317:4317;挂载 otel-collector/config.yaml |
| Prometheus | prom/prometheus:latest | 9090:9090,启用 remote-write receiver,挂载 prometheus/prometheus.yml |
| Grafana | grafana/grafana:11.5.2 | 3100:3000,GF_INSTALL_PLUGINS=grafana-clickhouse-datasource,预置仪表盘与数据源 provisioning |
网络与数据卷
Compose 底部声明了 4 个 bridge 网络,实现流量分层隔离:
rivet-core-network:核心可观测性服务(ClickHouse、Prometheus、Grafana、OTel Collector)互通;rivet-network:主要业务网络(Engine、Runner、NATS、Postgres、Vector);rivet-network-engine-peer:Engine 节点间 peer 通信专用;rivet-network-to-core:业务服务访问核心服务的桥接网络。
数据持久化使用 6 个具名卷:clickhouse-data、prometheus-data、grafana-data、postgres-data、vector-server-data-default、vector-client-data-default。
Rivet Engine 配置详解:三节点为何使用相同配置
config.jsonc(rivet-engine/0、1、2三份内容一致)展示了单数据中心多节点下的拓扑声明方式:
{ "auth": { "admin_token": "dev" }, "api_peer": { "host": "0.0.0.0" }, "topology": { "datacenter_label": 1, "datacenters": { "default": { "datacenter_label": 1, "is_leader": true, "peer_url": "http://rivet-engine-0:6421", "public_url": "http://rivet-engine-0:6420", "valid_hosts": ["rivet-engine-0", "127.0.0.1", "localhost"] } } }, "outbound": { "allow_private_networks": true }, "postgres": { "url": "postgresql://postgres:postgres@postgres:5432/rivet_engine" }, "clickhouse": { "http_url": "http://clickhouse:9300", "native_url": "http://clickhouse:9301", "username": "system", "password": "default" }, "nats": { "addresses": ["nats:4222"] } }字段含义与实现要点:
- auth.admin_token:管理令牌,
dev为开发环境默认值,Runner 与runner-config-init均使用它做 Bearer 鉴权; - topology.datacenter_label / datacenters:声明当前数据中心编号(1)及数据中心
default的拓扑信息。is_leader: true表示该数据中心内存在 leader 节点,peer_url指向 Engine 0 的 peer 端口(6421),public_url指向公共端点(6420); - valid_hosts:允许通过 Host 头访问的域名白名单,包含容器名与回环地址,这也是宿主机能直接访问
localhost:6420的前提; - outbound.allow_private_networks:允许 Runner 访问私有网络,适用于开发环境;
- postgres.url:指向
postgres服务的rivet_engine数据库,与 postgres/init-db.sh 中创建的库一致; - clickhouse / nats:分别指向聚合侧存储与消息总线。
多节点场景下三份配置完全相同是合理的:Engine 节点通过 NATS 与 peer 端口自行完成服务发现与 leader 选举,配置只需描述「数据中心有哪些端点」,而无需逐节点差异化(如需真正的多数据中心拓扑,可参考 dev-multidc 模板,每个数据中心单独一份配置)。
可观测性链路:日志、追踪与指标如何流转
Vector:客户端 → 聚合器 → ClickHouse
vector-server/vector.yaml 配置了聚合器(Aggregator)实例,负责接收所有 Vector 客户端上报的数据:
- sources:
vector(0.0.0.0:6000,Vector v2 协议)、tcp_json(6100)、http_json(6200,JSON 编码)、internal_metrics、internal_logs; - transforms:
clickhouse_dynamic_events_filter过滤出source == "clickhouse"的事件,再由clickhouse_dynamic_events_transform用 VRL 脚本重排数据——提取database、table、columns元数据,合并默认namespace: "rivet"后生成待写入对象; - sinks:
clickhouse_dynamic_events使用 ClickHouse sink 动态写入{{ __database }}.{{ __table }},gzip 压缩、批量提交(max_events: 1000、timeout_secs: 10);console_vector_logs将 Vector 自身日志以 JSON 输出到控制台便于排查。
vector-client则运行在各业务节点侧,负责采集日志并转发给vector-server(depends_on保证其晚于聚合器启动)。
OpenTelemetry Collector:OTLP + Prometheus 抓取
otel-collector/config.yaml 定义了完整的接收-处理-导出管线:
- receivers:OTLP gRPC(4317)与 HTTP(4318);Prometheus 抓取器每 15 秒抓取
rivet-engine-0/1/2:6430的指标; - processors:
resource处理器为所有数据注入rivet.project=dev、rivet.datacenter=default资源属性;batch处理器 5 秒聚合、单批最多 10000 条; - exporters:logs/traces 写入 ClickHouse 的
otel库(otel_logs、otel_traces表,async_insert: true、TTL 72 小时、LZ4 压缩、自动建表);metrics 通过 Prometheus remote write 推送到prometheus:9090/api/v1/write。
Engine 容器通过RIVET_OTEL_*环境变量接入该 Collector,构成「Engine → OTLP → Collector → ClickHouse/Prometheus」的完整可观测性闭环。ClickHouse 初始化脚本 01-create-otel-table.sql 配合create_schema: true保证表结构就绪。
Grafana 与 Prometheus
Prometheus 使用 prometheus/prometheus.yml 作为抓取配置,并开启--web.enable-remote-write-receiver接收 Collector 的指标。Grafana 通过 provisioning 自动接入数据源(ClickHouse 数据源插件grafana-clickhouse-datasource随环境变量GF_INSTALL_PLUGINS自动安装),并在 grafana/dashboards 中预置了覆盖api、cache、epoxy、futures、gasoline、guard、operation、pegboard、tokio、traces等模块的仪表盘 JSON,启动后访问http://localhost:3100即可查看。
与其他开发模板的对比与选型
在 self-host/compose/template/src/config.ts 中,Rivet 提供了 5 种开发模板,可按需选型:
| 模板 | 网络模式 | 拓扑 | 适用场景 |
|---|---|---|---|
dev | bridge | 1 数据中心 × (1 Engine + 1 Runner) | 最小化单节点开发 |
dev-multinode | bridge | 1 数据中心 × (3 Engine + 3 Runner) | 本模板,验证多节点编排、leader 选举与 Runner 调度 |
dev-multidc | bridge | 3 数据中心 × (1 Engine + 1 Runner) | 多数据中心容灾与就近路由 |
dev-multidc-multinode | bridge | 3 数据中心 × (3 Engine + 3 Runner) | 最完整的多数据中心多节点拓扑 |
dev-host | host | 1 数据中心 × (1 Engine + 1 Runner) | 需要直接使用宿主机网络/端口联调 |
如果目标是理解「多节点下 Engine 如何协作、多个 Runner 如何被调度」,dev-multinode是最轻量的切入方案;dev-multidc-multinode则是前者的多数据中心扩展版,其 README 与配置结构可供进阶参考。
使用注意事项
- 不要直接编辑生成文件:目录由模板生成器自动产出,手工修改会在下次生成时被覆盖。如需调整拓扑(如增减 Engine 数量),应修改模板源码 self-host/compose/template/src/config.ts 中的
TEMPLATES定义后重新生成,而非直接改docker-compose.yml。 - 端口冲突:Engine(6420)、Runner(5050)、PostgreSQL(5432)、Grafana(3100)、Prometheus(9090)、NATS(4222)均映射到宿主机,启动前请确认这些端口未被占用。
- 首次构建耗时:
engine-full目标包含前端构建(BUILD_FRONTEND: 'true'),首次docker-compose up -d会经历较长的镜像构建过程,Engine 健康检查也配置了 30 秒的start_period,请耐心等待docker-compose ps中全部服务转为 healthy。 - 凭证均为开发默认值:
admin_token、Postgres 用户密码、ClickHouse 密码均为dev/postgres/default,仅适用于本地开发,切勿直接用于生产环境。
通过docker-compose up -d拉起整套环境后,即可通过http://localhost:6420访问 Engine 公共端点、http://localhost:5050访问 Runner,并用docker-compose logs -f与 Grafana(http://localhost:3100)观察日志、追踪与指标,完成多节点场景下的开发与调试。
【免费下载链接】actorsRivet Actors are the primitive for stateful workloads. Built for AI agents, collaborative apps, and durable execution.项目地址: https://gitcode.com/GitHub_Trending/riv/actors
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考