The services that make up starts, at a glance. Ports are the host-mapped ports from
docker-compose.yml ; inside the stack, services
reach each other over their *_GRPC FQDNs (see
env & service discovery ). Each of these is one of the
three service shapes .
Service
Lang
Shape
Role
Host port
Health
core-database
Go
data plane
The only Postgres writer; codegen’d Connect/gRPC (h2c)
8080
/healthz
core-identity
Py
gateway
Validates Logto tokens; JIT user provisioning
8001
/healthz
core-storage
Py
data plane
Blob storage + transcode/HLS (native gRPC, ffmpeg)
8081
/healthz
core-mcp
Go
gateway
MCP tool registry + dispatch (h2c)
8090
/healthz
core-gateway-consumer
Py
gateway
Consumer trust boundary — authz, billing, streams
8082
/healthz
core-tool-agent
Py
worker
Agent One LLM worker (no ingress)
—
(no port)
core-tool-sansaarm
Py
worker
Sansaarm song generation (no ingress)
—
(no port)
core-tool-stitch
Py
worker
Stitch / studio composition (no ingress)
—
(no port)
Tool workers have no ingress — they poll the task queue and drain on SIGTERM. Other
tool workers (media, gpu, dna, conversion, …) follow the same shape; see the
tool catalog .
App
Lang
Role
Host port
soundverse-saas-2.0
Node
The SaaS web app (SPA + BFF) — frontend compose profile
3000
UI2.0
Node
Standalone in-browser studio (no backend) — frontend profile
3001
Container
Role
Host port
postgres
The one database (all domain schemas)
5432
redis
Cache, pub/sub (task:wake), SSE streams, rate-limit counters
6379
azurite
Azure Blob emulator (run make azurite-init once)
10000
Note
Ports are the local docker-compose defaults and can drift — treat
docker-compose.yml as authoritative. In staging/prod
these services run on Azure Container Apps with TLS on :443, discovered by FQDN, not these ports.