Standalone multi-node container runtime and gateway.
Desired-state reconciliation is the core model: apply / remove update cluster
and host specs; nodes reconcile Docker; the gateway watches routes and proxies
HTTP/WebSocket traffic to the owning node, including scale-to-zero cold starts
and always-on recovery for paid/latency-sensitive containers.
momo gateway --config cluster.yml
momo node --node-id node-a --store file://./momo-state
momo apply -f app.yml --node node-a
momo container idle set --app api --container web --mode always-on
momo remove app-id
momo status
momo doctorClient ──▶ [optional momo edge] ──▶ momo gateway ── Acquire/Release ──▶ momo node ──▶ Docker
│ │
└──────── shared store (file|sqlite|postgres) ─┘
| Role | Command | Responsibility |
|---|---|---|
| Edge | momo edge |
Optional TLS/HTTP front door (static PEMs or Let's Encrypt HTTP-01) |
| Gateway | momo gateway |
Route watch, per-node gRPC pool, HTTP/WebSocket proxy, /healthz /readyz /metrics |
| Node | momo node |
HostSpec → Docker reconcile, Acquire/Release, idle reaper, heartbeats |
| Operator | momo apply / container idle set / remove / … |
Mutate desired state; export/import for backup and DR |
Runtime fields (status, active_requests, last_access, backend_addr) live
only in node process memory — never in desired-state specs. Per-container idle
policy (idle.mode / timeout_secs) is desired state; effective values appear
in momo status.
# Terminal 1 — node (file store for single-process dev)
momo node --node-id node-a --store file://./momo-state --auto-register
# Or use SQLite for single-host multi-process:
# momo node --node-id node-a --store sqlite://./momo.db --auto-register
# Terminal 2 — gateway
momo gateway --store file://./momo-state --bind 127.0.0.1:8080
# Apply a sample app (build images first with `make samples`)
momo apply -f examples/simple-api/app.yml --node node-a --store file://./momo-state
# or: momo apply -f examples/api-with-db/app.yml --node node-a --store file://./momo-state
# Schema demo (placeholder image): examples/momo/app.ymlPublished container ports use loopback by default; set --advertise-addr on the
node when the gateway must reach backends on another host.
# On host B (shared store required — sqlite on shared disk or postgres):
momo node --node-id node-b --store postgres://… --auto-register \
--advertise-addr 10.0.0.12
momo apply -f examples/momo/app.yml --node node-b --store postgres://…See docs/production.md for systemd, auth/mTLS, and multi-node layout.
| URI | Use |
|---|---|
file://./momo-state |
Local single-process development |
sqlite://./momo.db |
Single-host multi-process |
postgres://… |
Multi-host production |
crates/
├── momo-cli/ # momo binary — gateway, node, operator commands
├── momo-core/ # desired/runtime models, validation, error codes, config
├── momo-spec/ # AppSpec parse/validate/project/diff + scheduler
├── momo-store/ # Store trait + file / sqlite / postgres adapters
├── momo-proto/ # node gRPC types
├── momo-node/ # node mode runtime
└── momo-gateway/ # gateway mode runtime
| Crate | Role |
|---|---|
momo-cli |
Single momo binary |
momo-core |
Desired-state + runtime boundaries, momo_* error codes, MOMO_* config |
momo-spec |
Spec parsing, validation, HostSpec projection, route index, scheduler |
momo-store |
Desired-state store trait + file / SQLite / Postgres adapters |
momo-proto |
Node gRPC API |
momo-node |
Docker reconcile + Acquire/Release + status |
momo-gateway |
Route watch + proxy + metrics |
cargo build --workspace
cargo run -p momo-cli -- --help
cargo run -p momo-cli -- --version
cargo test --workspace
make edge-smoke # optional: momo-edge + gateway header unit gatesBuilding momo edge needs OpenSSL (Pingora). On macOS with Homebrew:
export OPENSSL_DIR="$(brew --prefix openssl@3)"
export PKG_CONFIG_PATH="$(brew --prefix openssl@3)/lib/pkgconfig"Linux CI/Docker install pkg-config + libssl-dev (runtime: libssl3).
Install the primary binary:
make install # installs `momo` to $(PREFIX)/bin
make install PREFIX=$HOME/.local
sudo make install-systemd # Linux: units + /etc/momo/momo.env exampleRelease tarballs (linux/darwin amd64+arm64) and the container image are published
from GitHub Actions on v* tags. CI required checks: fmt, clippy, test,
cargo audit.
# Optional local compose (gateway + node + shared sqlite volume)
docker compose -f deploy/docker-compose.momo.yml up --build
# Optional edge profile (needs PEMs under deploy/certs/):
# docker compose -f deploy/docker-compose.momo.yml --profile edge up --buildEnvironment variables use the MOMO_ prefix. Defaults target localhost development.
| Variable | Default | Purpose |
|---|---|---|
MOMO_ENV |
dev |
dev or production (production fails fast on insecure config) |
MOMO_STORE |
unset | Desired-state store URI (file://, sqlite://, or postgres://) |
MOMO_GATEWAY_BIND |
127.0.0.1:8080 |
Gateway HTTP listen |
MOMO_NODE_GRPC_BIND |
127.0.0.1:50051 |
Node gRPC listen |
MOMO_NODE_METRICS_BIND |
127.0.0.1:9101 |
Node /metrics listen |
MOMO_NODE_ID |
unset | Node identity (required in production) |
MOMO_DOCKER_HOST |
(Docker default) | Docker engine endpoint |
MOMO_RECONCILE_INTERVAL_SECS |
5 |
Node reconcile interval |
MOMO_AUTH_TOKEN |
unset | Shared secret for gateway ↔ node RPC |
MOMO_LOG_FORMAT |
text |
text or json (production requires json) |
MOMO_ALLOW_PUBLIC_BIND |
unset | Set 1 to allow 0.0.0.0 binds |
MOMO_ALLOW_FILE_STORE |
unset | Set 1 to allow file:// stores when MOMO_ENV=production |
MOMO_ACTOR |
$USER |
Actor identity recorded in store audit log |
MOMO_TLS_CERT / MOMO_TLS_KEY |
unset | TLS material (node server / secure transport) |
MOMO_TLS_CA |
unset | CA for verifying peers |
MOMO_TLS_CLIENT_CERT / MOMO_TLS_CLIENT_KEY |
unset | Client identity for mTLS |
MOMO_GATEWAY_URL |
unset | Base URL for momo doctor gateway /healthz probe |
Production (MOMO_ENV=production) requires store URI, auth token, secure
transport, and JSON logs before gateway/node will proceed past config validation.
momo gateway --help # config, store, bind, TLS/auth, log format
momo node --help # run node, or node link|drain|undrain|unlink
momo node link --help # register a node in the store
momo apply --help # -f, --node, --store, --dry-run, --diff, --wait
momo remove --help # app id, --drain-timeout, --force, --dry-run
momo status --help # cluster / --node / --app (desired + observed)
momo inspect --help # detailed app view
momo routes --help # RouteSpec listing
momo nodes --help # linked nodes + availability
momo validate --help # schema + policy check (no store write)
momo diff --help # planned changes vs store (structured JSON kinds)
momo doctor --help # store, nodes, images, volumes, production posture
momo export --help # backup desired state (yaml/json)
momo import --help # restore / replace desired stateLocal desired-state workflow:
momo node link --node-id node-a --grpc-endpoint http://127.0.0.1:50051 \
--store file://./momo-state
momo validate -f examples/simple-api/app.yml
momo apply -f examples/simple-api/app.yml --node node-a --store file://./momo-state --wait
momo status --store file://./momo-state --output json
momo export --store file://./momo-state -o backup.yaml
momo remove simple-api --store file://./momo-state # drains first; --force if needed
momo node drain node-a --store file://./momo-state # block new placements
momo doctor --store file://./momo-state --gateway-url http://127.0.0.1:8080Force unlink orphans: momo node unlink <id> --force removes the node from
ClusterSpec but leaves AppSpecs/HostSpecs that still reference it. Remove or
re-apply those apps afterward.
Use --output json for machine-parseable output (schema_version: momo.cli.v1
on success; error.code is a stable momo_* string on failure).
Exit codes: 0 success/help, 1 validation/config/operational errors, 2 usage
(unknown subcommand / bad args).
Schema reference: docs/spec-schema.md.
| Doc | Purpose |
|---|---|
| docs/architecture.md | Gateway / node / store architecture |
| docs/spec-schema.md | AppSpec / HostSpec / ClusterSpec reference |
| docs/cli-reference.md | CLI command reference |
| docs/production.md | Production deploy, systemd, multi-node |
| docs/security.md | Auth, mTLS, binds, unsafe Docker, secrets |
| docs/metrics.md | Prometheus metrics catalog |
| docs/runbook.md | Ops triage, backup/restore, upgrades |
| deploy/systemd/README.md | systemd install for Momo |
MIT