How Komodo manages the server, how stacks map to environments, and how game containers plug into the platform.
One Ubuntu server. System Nginx handles SSL and routes traffic. Komodo manages all Docker stacks. Each stack is an independent group of containers with its own lifecycle.
Test and prod are identical stacks running on different ports. Komodo manages each independently — deploy, rollback, and restart one without touching the other. Both point at this git repo; prod tracks main, test tracks main or a specific branch.
main branch · auto-redeploy on image push · env in Komodo secretsAll stacks run on the same server and Docker network. Auth is stateless (JWT). The main Postgres is the single source of truth — game containers use dedicated schemas, never their own separate databases.
esport-arena.no (root domain) — automatically sent to every path including /cs2/*
CLERK_PUBLISHABLE_KEY — user sees one seamless login
auth() — Clerk middleware reads the cookie, no extra config needed
Authorization: Bearer <clerk-token>
CLERK_JWKS_URL — Komodo injects via env, never in repo
publiccs2pubg?search_path=cs2
public schema directly
postgres:5432, earena-backend:8010
OTEL_EXPORTER_OTLP_ENDPOINT=http://openobserve:5081 — logs and traces ship automatically
service, level, trace_id — searchable in OpenObserve UI
console.log in production — ESLint rule blocks it. Use the structured logger wrapper instead
The frontend has dynamic game routes at /(games)/[slug]/... and game-specific routes like /pubg/tournament/[slug].
Each game slug maps to a dedicated API container via an environment variable.
Adding a new game means adding a new container stack — the frontend needs no structural changes.
Komodo reads compose.yaml directly from this Git repo. You never SSH to deploy manually — Komodo handles pull, build, and restart. Secrets live in Komodo, never in the repo.
The pattern is the same for every game. Four steps from idea to live on the platform.
Add stacks/<game>-api/compose.yaml in core-infrastructure. Define the container image, port, and env file.
In Komodo UI, create a new Stack pointing at stacks/<game>-api/ in this repo. Add secrets to Komodo — never in the repo.
In Komodo, add <GAME>_API_URL=http://<game>-api:400x to the earena-prod and earena-test stack environments.
In sanity-web, add routes under app/[locale]/(games)/<game>/. Fetch from the game API using the env var. Create a feature doc first.
Heavy game-specific UI — 3D map renderers, live telemetry dashboards, matchmaking flows — does not belong in the main sanity-web bundle.
Each game gets its own Next.js container with its own basePath, served under the same domain via Nginx.
Users see one seamless URL; each app ships and scales independently.
| Concern | Single sanity-web bundle | Multi-Zones (separate container) |
|---|---|---|
| Bundle size | 3D map renderer + telemetry shipped to every visitor | Only loaded when user navigates to /cs2/* |
| Deploy risk | CS2 bug can break the main platform | Fully isolated — redeploy cs-web without touching sanity-web |
| Scaling | Scale the entire app for one game's traffic spike | Scale cs-web independently during CS2 tournament day |
| Team ownership | All game features compete in one PR queue | CS2 team owns cs-web repo end to end |
| Cache strategy | Shared CDN cache invalidation | Game-specific cache headers per container |
// cs-web knows it lives under /cs2 const nextConfig = { basePath: '/cs2', assetPrefix: '/cs2', }; // Nginx routes /cs2/* → cs-web container // Clerk cookie domain shared: esport-arena.no // Session works seamlessly across both apps
| Stack | Path in repo | Env | Purpose |
|---|---|---|---|
| earena-test | stacks/earena/ | test | Staging environment — same stack, different ports |
| earena-prod | stacks/earena/ | prod | Main platform — frontend, backend, DB, worker |
| cs-web-test | stacks/cs-web/ | test | CS2 frontend Multi-Zone — basePath /cs2, port 3021 |
| cs-web-prod | stacks/cs-web/ | prod | CS2 frontend Multi-Zone — basePath /cs2, port 3020 |
| cs2-api | stacks/cs2-api/ | game | CS2 game data API — tournaments, maps, stats |
| pubg-api | stacks/pubg-api/ | game | PUBG game data API — tournaments, telemetry, players |
| cs2-server | stacks/cs2/ | dedicated | CS2 dedicated game server — port 27015 |
| openobserve | stacks/openobserve/ | obs | Centralized logs + traces — OTLP on :5081, UI on :5080 |
| komodo | stacks/komodo/ | system | Komodo Core + Periphery + MongoDB |
| playbook | stacks/playbook/ | docs | Dev playbook static site — port 9200 |