Run the full stack from source
Running a service from source — go run / uv run on the host instead of a
container — is what you do when you’re actually changing that service: fast reload,
a debugger attached, breakpoints. You rarely run the whole fleet this way. The usual
shape is one service from source against the rest in Docker: bring the stack up with
make up, stop the one container you’re editing, and
run its repo directly.
This page gives the full manual bring-up order so you understand the dependency chain, then the practical “one from source, rest in Docker” recipe.
Why bottom-up
Section titled “Why bottom-up”Services dial downward: the frontend needs the gateway; the gateway needs
core-database + core-identity; the tool workers need core-mcp + core-storage; and
everything needs Postgres and Redis. Start from the bottom so each process finds its
dependencies already listening — otherwise the gRPC clients spin on connect.
Canonical local ports
Section titled “Canonical local ports”Run each source process on the same host port make up publishes, so one .env works
whether a dependency is in Docker or on the host. These are verified against
docker-compose.yml:
| Service | Shape | Listens on (from source) | Others reach it via |
|---|---|---|---|
| postgres | infra | localhost:5432 |
DATABASE_DSN |
| redis | infra | localhost:6379 |
REDIS_ADDR |
| azurite | infra (blob emulator) | localhost:10000 |
AZURE_CONNECTION_STRING |
| core-database | Go, gRPC/h2c | :8080 |
CORE_DATABASE_GRPC |
| core-identity | Python, HTTP | :8001 |
CORE_IDENTITY_GRPC |
| core-storage | Python, gRPC | :8081 |
CORE_STORAGE_GRPC |
| core-mcp | Go, gRPC/h2c | :8090 |
CORE_MCP_GRPC / CORE_MCP_URL |
| core-gateway-consumer | Python, gRPC | :8082 |
CORE_GATEWAY_CONSUMER_GRPC |
| a tool worker | Python, no ingress | — (polls the queue) | — |
| soundverse-saas-2.0 | Node, Next.js | :3000 |
— (the browser) |
Bring-up order
Section titled “Bring-up order”Each backend service reads its config from a local .env in its own repo
(cp .env.example .env) — see Configuring .env for the
shared-secret and TLS-flag details. Every step below assumes that file exists.
-
Postgres + Redis + Azurite. The pragmatic path is to run just the stateful containers from the super-repo and leave them up:
Terminal window docker compose up -d postgres redis azuritemake azurite-init # create the private/public/live blob containers (once)On a first boot (empty data volume) Postgres auto-runs the schema init, so step 2 is already done for you. Endpoints: Postgres
localhost:5432, Redisredis://localhost:6379/0, Azurite blob onlocalhost:10000. -
Apply the schema — only if you’re using a native Postgres.
core-databaseruns no migrations; it expects the schema to already exist. Load, in FK-safe order: firstcompose/postgres/00-prelude.sql(extensions, schema namespaces, thestorage.uuid_generate_v7()stub that breaks the storage⇄generation cycle), then the per-domain DDL files undersoundverse-proto/proto/soundverse_proto/<domain>/v1/schema.sql(e.g.identity,storage,chat,generation/task,generation/tool,billing/tokens). The compose loader10-load-schemas.shis the reference for the exact order. core-database Go — the single Postgres door; everything else is a client of it.
Terminal window cd core-databasego mod tidygo run ./cmd/server # LISTEN_ADDR defaults to :8080Needs Postgres (and Redis for caching). It pings the database at startup and exits if the schema is missing — that’s your signal step 2 didn’t run.
core-identity Python — validates Logto OIDC tokens (JWKS) and just-in-time provisions users into
core-database. It’s a FastAPI HTTP app, so drive it with hypercorn (no Makefile in this repo):Terminal window cd core-identityuv syncuv run hypercorn app.main:app -b 0.0.0.0:8001Needs
core-database(CORE_DATABASE_GRPC). Browser login needs a real Logto OIDC app; token validation works offline. See Configure Logto.core-storage Python — content-deduped blob uploads and the FLAC → CMAF/HLS transcode. Also no Makefile; run the module directly:
Terminal window cd core-storageuv syncAPP_PORT=8081 uv run python -m app.mainNeeds
core-databaseand a blob backend. PointAZURE_CONNECTION_STRINGat your Azurite from step 1, or core-storage falls back to Azure managed identity and fails on a laptop. Uploads 404 until you’ve runmake azurite-init.core-mcp Go — the MCP tool registry + the second billing pipeline the agent runs through.
Terminal window cd core-mcpgo mod tidygo run ./cmd/server # LISTEN_ADDR defaults to :8090Needs
core-database,core-storage, and Redis.core-gateway-consumer Python — the authenticated edge the frontend talks to (authz → rate-limit → price → reserve → queue). This repo ships a Makefile:
Terminal window cd core-gateway-consumermake syncAPP_PORT=8082 make run # make run = uv run python -m app.mainNeeds
core-database,core-identity, and Redis.A tool worker Python — pick one, e.g.
core-tool-sansaarm(song-gen) orcore-tool-agent. Workers have no ingress — they poll the task queue — so there’s no port to set:Terminal window cd core-tool-sansaarmmake syncmake run # uv run python -m app.mainNeeds
core-database(queue + registry),core-storage, and Redis. Nothing generates until at least one worker is up: queued tasks sit at “planning…”, and because the AI Tools panel is registry-only (no curated fallback), it stays empty until a worker boots and self-registers its tools.soundverse-saas-2.0 Node — the Next.js SaaS UI.
Terminal window cd soundverse-saas-2.0npm installnpm run dev # next dev on :3000Needs
core-gateway-consumer(CORE_GATEWAY_CONSUMER_GRPC). Full frontend details, including the standalone UI2.0 studio, are in Run the frontends.
The traps that bite bring-up
Section titled “The traps that bite bring-up”What needs a real credential
Section titled “What needs a real credential”The whole stack boots and stays healthy with zero external accounts. Only features that
reach outside the fleet need a secret in .env: agent LLM turns (an LLM proxy key), Sansaarm
song generation (its API creds), and browser login (a Logto OIDC app). The full matrix is in
What works offline vs. what needs secrets.
Related
Section titled “Related”- Quick start with docker-compose — the one-command path
- Configuring .env — the shared secret, TLS flags, injection
- Run the frontends — saas-2.0 and the standalone UI2.0
- Prerequisites & toolchains — Go, Python + uv, Node versions
- Service catalog — every service, its shape, and its port
- Troubleshooting — the failures you’ll actually hit