One command starts the full stack with hot-reload from your local source files:
docker compose -f deploy/docker-compose.dev.yml up -dOpen http://localhost:3000. All services watch the source tree and reload automatically — no manual rebuild needed.
To stop:
docker compose -f deploy/docker-compose.dev.yml downTo also remove data volumes:
docker compose -f deploy/docker-compose.dev.yml down -v| Service | Technology | Port | Hot-reload |
|---|---|---|---|
| Gateway (Caddy) | caddy:2-alpine | 3000 (host) | — |
apps/web |
React + TanStack Start + shadcn/ui | 3000 (internal) | Vite HMR |
services/api |
Go + Gin | 8080 (internal) | air |
services/realtime |
Node.js + Socket.IO | 3001 (internal) | bun --watch |
services/ai-agent |
Python + FastAPI + OpenHands SDK | 8080 (internal) | source volume |
| PostgreSQL | postgres:16-alpine | 5432 | — |
| Valkey | valkey/valkey:8-alpine | 6379 | — |
| MinIO S3 API | minio/minio | 9000 | — |
| MinIO Console | minio/minio | 9001 | http://localhost:9001 (user: minioadmin, pass: minioadmin) |
The Caddy gateway (port 3000) routes /api/v1/… to the API, socket traffic to realtime, and /storage/… to MinIO. apps/web is served at the root.
- Docker with the Compose plugin
That is the only hard requirement for the full containerized stack. The services build their own images from Dockerfile.dev in each service directory.
If you only want PostgreSQL and Valkey (to run services on the host yourself):
docker compose -f deploy/docker-compose.dev.yml up -d postgres valkeyFor faster feedback loops or IDE-integrated debugging, you can run individual services directly on the host and point them at the containerized infra.
Prerequisites for host-side development:
- Go 1.23+ (for
services/api) - Bun (for
apps/webandservices/realtime) - Python 3.12+ with uv (for
services/ai-agent)
cd services/api
cp .env.example .env # first time — credentials match docker-compose defaults
make run # uses air for hot-reloadcd apps/web
bun install # first time only
bun run dev # Vite dev server at http://localhost:3000cd services/realtime
bun install # first time only
bun run devcd services/ai-agent
uv sync # first time only
uv run uvicorn src.main:app --reload --port 8000Migrations are plain SQL files under services/api/migrations/ named in lexicographic order. They run automatically when the Postgres container first starts (mounted at /docker-entrypoint-initdb.d).
To apply migrations manually against a running instance:
cd services/api
make migrate-up # requires DATABASE_URL to be set| Resource | Value |
|---|---|
| App login | admin / adminpassword |
| PostgreSQL | paca:paca@localhost:5432/paca |
| MinIO console | minioadmin / minioadmin at http://localhost:9001 |
| Agent API key | dev-agent-api-key-change-in-production |
These are intentionally weak defaults — never use them in production.
services/apiowns all persistent state changes and publishes domain events to Valkey Streams.services/realtimeconsumes those events and fans them out to Socket.IO clients.services/ai-agentreads agent trigger events from a separate Valkey Stream and manages Docker containers for OpenHands conversations.apps/mcpis stateless; run it withnpx @paca-ai/paca-mcppointed at the running API.