Skip to content

Docker Setup

Complete Docker Compose configuration for running the Kaizen Core stack.

Quick Start

# From repository root
docker compose up -d
 
# Check status
docker compose ps
 
# View logs
docker compose logs -f write-node
 
# Access services
open http://localhost:3000  # Tester
open http://localhost:3003  # Grafana (admin/kaizen)

Architecture

Docker Architecture

Services

ServicePortDescription
write-node8545, 9000Sequencer (RPC+WS at /ws, gRPC)
read-node-aggressive8547, 9001Low-latency queries
read-node-archive8548, 9002Full history
proxy8546RPC proxy (WS at /ws)
oracle8550Price aggregator
bridge3002Deposit relay
solver3001Quote provider
settler9091 (metrics)Settlement service
postgres5432Indexer database
tester3000Frontend app
grafana3003Monitoring
prometheus9090Metrics
loki3100Logs

Read Node Modes

Aggressive Mode

  • Purpose: Low-latency queries for real-time applications
  • Pruning: Keeps ~16 minutes of history
  • Use case: Trading UI, WebSocket, simulateTransaction
  • Disk: Minimal

Archive Mode

  • Purpose: Full history for indexing and analytics
  • Pruning: Disabled
  • Use case: Historical queries, auditing
  • Disk: Grows over time

RPC Routing

The proxy routes requests automatically:

Method TypeTargetExamples
Writewrite-nodekaizen_sendTransaction
Readread-node-aggressivekaizen_getAccount, kaizen_simulateTransaction
WebSocketread-node-aggressive (via broadcast hub)All subscriptions

:::tip Unified Endpoint Frontend only needs localhost:8546 for both RPC and WebSocket. :::

WebSocket Broadcast Hub

The proxy uses a broadcast hub architecture for WebSocket connections:

  • Single upstream WebSocket connection to read-node (not N connections for N clients)
  • Efficient message routing - messages routed only to clients with matching subscriptions
  • Automatic reconnection with exponential backoff
  • Configurable buffer via BROADCAST_CAPACITY (default: 4096)

See RPC Proxy for detailed documentation.

Configuration Files

FileDescription
docker/config/write-node.tomlSequencer configuration
docker/config/read-node-aggressive.tomlAggressive pruning
docker/config/read-node-archive.tomlArchive mode

Environment Variables

VariableDescriptionDefault
BRIDGE_PRIVATE_KEYBridge relayer keyTest key
SOLVER_PRIVATE_KEYSolver signer keyTest key
SETTLER_PRIVATE_KEYSettler keyTest key
POSTGRES_USERDatabase usernamekaizen
POSTGRES_PASSWORDDatabase passwordkaizen
GRAFANA_ADMIN_PASSWORDGrafana passwordkaizen

Test Accounts (Development Only)

ServiceAddressRole
Bridge0x97e6f3163d327d4af7dA38AA779158d2a67A746DRelayer
Solver0x88211b41fdd061279477d7801d0A8A04A78aF6a9Quote signer

Development Commands

# Build specific services
docker compose build write-node oracle proxy
 
# Rebuild after changes
docker compose build --no-cache <service>
docker compose up -d <service>
 
# Run without monitoring
docker compose up -d write-node read-node-aggressive oracle mock-bridge mock-solver settler proxy tester
 
# View specific logs
docker compose logs -f write-node oracle

Troubleshooting

Node Won't Start

  • Check if ports are in use
  • Verify config syntax: cargo run -- init

Read Nodes Not Syncing

  • Check gRPC connectivity to write-node:9000
  • Verify write_node_addr in read node config

Grafana Not Showing Data

Build Failures

docker builder prune
docker compose build --no-cache