Self-hostable open source developer infrastructure platform. Six independent microservices containerized with Docker, brought up with a single command.
make up
┌─────────────────────────────────────────┐
│ gateway :3000 │
│ (routing + auth enforcement) │
└───┬─────────┬─────────┬─────────────────┘
│ │ │
┌────────────┘ ┌──────┘ ┌─────┘
▼ ▼ ▼
┌──────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────┐
│ auth │ │ workflow- │ │ feature- │ │ metrics │
│ :3001 │ │ engine:3002 │ │ flags :3003 │ │ :3004 │
└────┬─────┘ └──────┬───────┘ └──────┬───────┘ └────┬────┘
│ │ │ │
┌────▼────┐ ┌──────▼───────┐ ┌────▼────┐ ┌──────▼──────┐
│Postgres │ │ Postgres │ │ Redis │ │ TimescaleDB │
│(users, │ │(event store) │ │ (cache) │ │ (metrics) │
│ roles) │ └──────────────┘ └─────────┘ └─────────────┘
└─────────┘
| Service | Port | Description |
|---|---|---|
gateway |
3000 | HTTP reverse proxy with auth header enforcement |
auth |
3001 | RS256 JWT issuance, RBAC with least-privilege permissions |
workflow-engine |
3002 | Durable workflow execution with event sourcing + deterministic replay |
feature-flags |
3003 | Sub-5ms flag evaluation via Redis cache; WebSocket push invalidation |
metrics |
3004 | TimescaleDB ingestion pipeline with continuous aggregates |
dashboard |
3005 | React status dashboard |
- Docker and Docker Compose
openssl(for key generation)
make keygenCopy the output JWT_PRIVATE_KEY and JWT_PUBLIC_KEY lines into a .env file (see .env.example).
make up# Register a user
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","password":"hunter2hunter"}'
# Log in and get a JWT
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","password":"hunter2hunter"}'
# Evaluate a feature flag
curl -X POST http://localhost:3000/flags/evaluate \
-H "Content-Type: application/json" \
-d '{"flagKey":"dark-mode","context":{"userId":"u1"}}'Open http://localhost:3005 to see the dashboard.
Event sourcing in the workflow engine — every state transition is appended to an immutable event log. On failure, the executor replays the log from the beginning; already-completed steps are skipped because their step.completed events are already in the log. This guarantees exactly-once step execution without a distributed lock.
Redis-backed feature flag cache — flags are cached in Redis with a configurable TTL (default 5 s). When a flag is updated, the service publishes an invalidation message on a Redis pub/sub channel. All service instances subscribed to that channel drop their local entry. Connected browser clients receive a WebSocket push and can refetch immediately, giving sub-5 ms evaluation on cache hits.
RS256 JWTs — asymmetric signing means the auth service holds the private key; every other service only needs the public key to verify tokens independently without calling back to auth on every request.
TimescaleDB for metrics — metrics are buffered in memory and flushed in batch writes on a 1-second interval. TimescaleDB's hypertable partitions data by time automatically; a continuous aggregate computes per-minute rollups, and a retention policy drops raw data after 30 days.
# Install all service dependencies locally
make dev-install
# Run a single service in watch mode
cd services/auth && npm run devMIT