Skip to content

Architecture

Momo is a standalone multi-node container runtime and gateway. Desired state lives in a shared store; nodes reconcile Docker; the gateway routes and proxies.

User / API Client
momo edge (optional; Pingora TLS / Let's Encrypt HTTP-01)
or external reverse proxy / cloud LB
│ Host + X-Forwarded-* preserved
momo gateway ── watch routes/nodes ──▶ Store (file | sqlite | postgres)
│ ▲
│ Acquire/Release gRPC (+ auth/mTLS) │ apply / remove / import
▼ │
momo node (per host) ── watch HostSpec ────────┘
Docker Engine
App containers (web / worker / db / …)

Host-based app routing stays in the gateway; the optional edge is a dumb TLS/LB front door.

Role Binary command Responsibility
Edge momo edge Optional public TLS/HTTP front door (static PEMs or Let’s Encrypt HTTP-01)
Gateway momo gateway Route index watch, per-node gRPC pool, HTTP/WebSocket reverse proxy, /healthz /readyz /metrics
Node momo node HostSpec reconcile, Acquire/Release, idle reaper, heartbeats, node /metrics
Operator momo apply / remove / … Mutate desired state; export/import for DR
Desired (store) Runtime (node memory only)
ClusterSpec, RouteSpec, NodeSpec status, active_requests
AppSpec, HostSpec last_access, backend_addr
Cluster policies Single-flight start handles

Runtime fields are never written into specs.

URI Use
file://./momo-state Local single-process development
sqlite://./momo.db Single-host multi-process
postgres://… Multi-host production
  1. Gateway receives HTTP with Host header.
  2. Lookup RouteSpec → owning node_id + container/port.
  3. Acquire on that node (cold-start + health gate if needed).
  4. Stream proxy to backend_addr (no full-body buffering).
  5. Release pin when the request or WebSocket ends (AcquireGuard).
  1. Idle reaper stops when active_requests == 0 and idle timeout elapsed.
  2. Concurrent cold Acquires share one Docker start (single-flight).
  3. Acquire health-gates before returning a backend.
  4. Dependencies start in order before the primary container.
  • Loopback binds unless MOMO_ALLOW_PUBLIC_BIND=1.
  • Unsafe Docker options rejected unless cluster policy allows them.
  • Production (MOMO_ENV=production) requires store, auth token, secure transport, JSON logs.
  • See Security.
Crate Role
momo-cli Single momo binary
momo-core Models, config, error codes
momo-spec Parse / validate / project / schedule
momo-store Store trait + file / SQLite / Postgres
momo-proto Node gRPC types
momo-node Docker reconcile + gRPC server
momo-gateway Route watch + proxy
momo-edge Optional Pingora edge (TLS / ACME)