Services & ports
The stack is a modular monolith: one Go codebase (platform-api) compiled into multiple binaries, plus a file service and the UI. Each service does one job.
HTTP services
Section titled “HTTP services”| Service | Port | Role |
|---|---|---|
platform |
4000 | React SPA — the web UI, served by nginx |
platform-api |
3000 | Main HTTP/WebSocket API: accounts, workflows, executions, credentials |
mcp-api |
3100 | MCP server exposing workflow nodes as tools, API-key gated |
webhook-api |
3200 | Inbound edge for workflow webhook triggers |
file-gateway-api |
3300 | Rule-gated file uploads/downloads (local disk, S3-compatible, or Bunny.net) |
Service ports are fixed inside the containers. On the compose network, services reach each other by service name (e.g. http://file-gateway-api:3300); the browser reaches them via the *_BASE_URL values in .env.
Workers
Section titled “Workers”| Service | Role |
|---|---|
task-worker |
Consumes queued workflow tasks from Redis Streams (TASK_RUNNER_MODE=queue) — scale this to add execution capacity |
event-relay-worker |
Drains the transactional event outbox from PostgreSQL — guarantees server-to-server events are never lost |
platform-api-migration |
One-shot: applies database migrations, then exits |
Data stores
Section titled “Data stores”| Store | Role |
|---|---|
| PostgreSQL 18 | The single database for all services |
redis |
Cache, pub/sub broadcast, distributed locks — ephemeral, safe to wipe. Not started by default: each of those subsystems runs in-process until you point it at Redis |
task-queue-redis |
The workflow task queue — AOF-persisted so queued work survives restarts. Only started in queue mode |
A default install runs neither Redis service — see Scaling out.
For how these pieces fit together (bounded contexts, eventing, execution model), see the architecture overview in the repository.