diff --git a/DOCKER.md b/DOCKER.md index d0623c1..0863d95 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -6,11 +6,12 @@ This guide covers everything you need to run any part of the Call of Code platfo ## Overview -The repository ships with **four Docker Compose configurations**: +The repository ships with **five Docker Compose configurations**: | File | Purpose | Services | |------|---------|----------| | `docker-compose.yml` | **API-only** dev (standalone) | `coc-api` | +| `docker/docker-compose.yml` | **All platforms** master stack | all 6 services | | `docker/coc-member/docker-compose.yml` | Full **COC Member** stack | `coc-api` + `server` + `web` | | `docker/coc-admin/docker-compose.yml` | Full **COC Admin** stack | `coc-api` + `server` + `web` | | `docker/callofcode.in/docker-compose.yml` | Full **callofcode.in** website stack | `coc-api` + `frontend` | @@ -76,6 +77,35 @@ cp docker/callofcode.in/.env.local.frontend.example docker/callofcode.in/.env.lo ## Running the Stacks +### All platforms together (master stack) + +Use this when you need all three platforms running simultaneously (e.g. testing cross-platform API behaviour or running the full suite locally): + +```bash +# From the repo root — watch mode recommended +docker compose -f docker/docker-compose.yml up --watch + +# Or standard mode +docker compose -f docker/docker-compose.yml up --build +``` + +All six services share a single `coc-network` bridge and a single `coc-api` instance: + +| Service | Container | Host port | Override env var | +|---------|-----------|-----------|------------------| +| `coc-api` | `3000` | **3000** | `COC_API_PORT` | +| `callofcode-frontend` | `3001` | **3001** | `CALLOFCODE_PORT` | +| `coc-admin-server` | `8000` | **8001** | `COC_ADMIN_BACKEND_PORT` | +| `coc-admin-web` | `5173` | **5174** | `COC_ADMIN_FRONTEND_PORT` | +| `coc-member-server` | `8000` | **8002** | `COC_MEMBER_BACKEND_PORT` | +| `coc-member-web` | `5173` | **5175** | `COC_MEMBER_FRONTEND_PORT` | + +> **Port remapping**: because `coc-admin` and `coc-member` both internally bind `8000` and `5173`, the master stack remaps them to unique host ports to avoid conflicts. Internal service-to-service communication (`API_URL=http://coc-api:3000`) still uses the original container ports. + +> **Env files required**: make sure all six env files exist before starting (see [Environment Setup](#environment-setup) above). + +--- + ### API-only (standalone development) Use this when you're only working on the `coc-api` itself: @@ -217,10 +247,14 @@ The dev compose files use `target: builder` so that devDependencies and the Pris The `dockerfile:` path in compose is relative to the `context`, not the compose file. Our configs set `context: ../..` (repo root) so `dockerfile: Dockerfile` resolves correctly. **Port already in use** -Set a custom port via the `PORT` env variable before running: +For the individual stacks, set a custom port via the `PORT` env variable: ```bash PORT=3001 docker compose up ``` +For the master stack, override the specific service port: +```bash +COC_API_PORT=3010 COC_ADMIN_BACKEND_PORT=8010 docker compose -f docker/docker-compose.yml up +``` **Prisma migration errors on startup** The `coc-api` container runs `prisma migrate deploy` on every start. If the DB is unreachable, the container will exit. Verify your `DATABASE_URL` and `DIRECT_URL` in `.env.local`. diff --git a/README.md b/README.md index e8f198e..adf8a04 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ COC-API/ │ ├── SiteContent.test.ts │ └── imageUtils.test.ts │ -├── docker/ # Platform-specific Docker Compose stacks +├── docker/ # Docker Compose stacks +│ ├── docker-compose.yml # ★ Master stack — all platforms together │ ├── coc-member/ # Full COC Member platform stack │ │ ├── docker-compose.yml │ │ ├── .env.local.backend.example @@ -145,9 +146,12 @@ bun install ### 4. Local development (Docker) -The project ships **four Docker Compose stacks**. Choose the one you need: +The project ships **five Docker Compose stacks**. Choose the one you need: ```bash +# ★ All platforms at once (recommended for full-stack development) +docker compose -f docker/docker-compose.yml up --watch + # API only (for coc-api development) docker compose up --build diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..449172e --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,173 @@ +# ============================================================================= +# Master Docker Compose — All Platforms +# Runs coc-api + all three frontends/backends together on a single network. +# +# Usage: +# docker compose -f docker/docker-compose.yml up --watch +# +# Port map: +# 3000 → coc-api (shared API) +# 3001 → callofcode.in (frontend) +# 8001 → coc-admin backend +# 5174 → coc-admin frontend +# 8002 → coc-member backend +# 5175 → coc-member frontend +# ============================================================================= + +name: coc-all + +services: + + coc-api: + image: coc-api + build: + context: .. + dockerfile: Dockerfile + target: builder # builder stage has devDeps + bun --watch + restart: unless-stopped + ports: + - "${COC_API_PORT:-3000}:3000" + env_file: + - ../.env.local # Local dev env vars (Supabase connection strings, etc.) + environment: + NODE_ENV: development + volumes: + - ../:/app + - /app/node_modules + - /app/node_modules/.prisma + command: > + sh -c "bunx prisma generate && + bunx prisma migrate deploy && + bun --watch src/server.ts" + develop: + watch: + - path: ../src + action: sync + target: /app/src + - path: ../package.json + action: rebuild + - path: ../bun.lock + action: rebuild + - path: ../prisma + action: rebuild + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 15s + networks: + - coc-network + + # callofcode.in — main website frontend + + callofcode-frontend: + image: callofcode07/callofcode:latest + pull_policy: missing + restart: unless-stopped + ports: + - "${CALLOFCODE_PORT:-3001}:3001" + env_file: + - callofcode.in/.env.local.frontend + environment: + - NODE_ENV=development + - API_BASE_URL=http://coc-api:3000 + depends_on: + coc-api: + condition: service_healthy + networks: + - coc-network + command: ["npm", "run", "dev"] + + # coc-admin — admin backend + + coc-admin-server: + image: callofcode07/coc-admin-backend:latest + pull_policy: missing + restart: unless-stopped + ports: + - "${COC_ADMIN_BACKEND_PORT:-8001}:8000" # remapped to 8001 to avoid conflict + env_file: + - coc-admin/.env.local.backend + environment: + - PORT=8000 + - API_URL=http://coc-api:3000 + - ALLOWED_ORIGINS=http://localhost:${COC_ADMIN_FRONTEND_PORT:-5174} + depends_on: + coc-api: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:8000/health"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 10s + networks: + - coc-network + + # coc-admin — admin frontend + coc-admin-web: + image: callofcode07/coc-admin-frontend:latest + pull_policy: missing + restart: unless-stopped + ports: + - "${COC_ADMIN_FRONTEND_PORT:-5174}:5173" # remapped to 5174 to avoid conflict + env_file: + - coc-admin/.env.local.frontend + environment: + - VITE_API_URL=http://localhost:8001 + depends_on: + coc-admin-server: + condition: service_healthy + networks: + - coc-network + + # --------------------------------------------------------------------------- + # coc-member — member backend + # --------------------------------------------------------------------------- + coc-member-server: + image: callofcode07/coc-member-backend:latest + pull_policy: missing + restart: unless-stopped + ports: + - "${COC_MEMBER_BACKEND_PORT:-8002}:8000" # remapped to 8002 to avoid conflict + env_file: + - coc-member/.env.local.backend + environment: + - PORT=8000 + - API_URL=http://coc-api:3000 + - ALLOWED_ORIGINS=http://localhost:${COC_MEMBER_FRONTEND_PORT:-5175} + depends_on: + coc-api: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:8000/health"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 10s + networks: + - coc-network + + # --------------------------------------------------------------------------- + # coc-member — member frontend + # --------------------------------------------------------------------------- + coc-member-web: + image: callofcode07/coc-member-frontend:latest + pull_policy: missing + restart: unless-stopped + ports: + - "${COC_MEMBER_FRONTEND_PORT:-5175}:5173" # remapped to 5175 to avoid conflict + env_file: + - coc-member/.env.local.frontend + environment: + - VITE_API_URL=http://localhost:8002 + depends_on: + coc-member-server: + condition: service_healthy + networks: + - coc-network + +networks: + coc-network: + driver: bridge