Skip to content

Getting Started

Prerequisites

No local Node.js, pnpm, or other toolchain installation is required. The Docker setup handles everything.

Starting Services

The root package.json provides convenience scripts for common setups. Infrastructure services (Postgres, Redis) always start regardless of profile.

ScriptWhat it does
pnpm dev:infraPostgres + Redis only (no profile)
pnpm dev:backendBackend services using existing images
pnpm dev:backend:buildRebuild base image + all backend images, then start
pnpm dev:fullstackBackend + frontend services using existing images
pnpm dev:fullstack:buildRebuild base image + all images, then start
pnpm dev:webNext.js dev server directly (no Docker)
pnpm dev:nativeNative app + Sanity dev servers (no Docker)

Web Development

The web app (Next.js) is not included in the Docker Compose setup. To develop on the web app, start the backend services and then run the Next.js dev server separately:

bash
# Terminal 1: start backend (API, GraphQL Router, etc.)
pnpm dev:backend

# Terminal 2: start the Next.js dev server
pnpm dev:web

This gives you native hot module replacement and fast refresh without the overhead of running Next.js inside a container.

When to Use :build

Use the :build variant when:

  • You just pulled changes from git (Dockerfiles or dependencies may have changed)
  • You changed Dockerfile.base, any app Dockerfile, or pnpm-lock.yaml
  • Docker images don't exist yet (fresh clone)

Use the non-:build variant for day-to-day development when images are already built. It skips the image build step and starts containers immediately.

TIP

The :build scripts run docker compose build base-node first to ensure the shared base image is up to date, then docker compose up --build to rebuild all app images. The non-:build scripts just run docker compose up with the appropriate profiles.

Running Profiles Directly

You can also use Docker Compose directly:

bash
# Backend only
docker compose --profile backend up

# Frontend only
docker compose --profile frontend up

# Monitoring only (Aspire dashboard)
docker compose --profile monitoring up

# Everything
docker compose --profile backend --profile frontend up

Service Ports

ServicePortURL
API3001http://localhost:3001
Match Gateway3002http://localhost:3002
GraphQL Router4000http://localhost:4000
Notifications4001http://localhost:4001
Identity4002http://localhost:4002
Loyalty4003http://localhost:4003
Business4004http://localhost:4004
API Gateway8888http://localhost:8888
Traefik Dashboard8880http://localhost:8880/dashboard/
Docs5173http://localhost:5173
Aspire Dashboard18888http://localhost:18888 -- see Observability
PostgreSQL5432postgresql://postgres:postgres@localhost:5432/main
Redis6379redis://localhost:6379

Common Tasks

Rebuild the Base Image

When Node.js or pnpm versions change in Dockerfile.base:

bash
docker compose build base-node

See Base Image for details.

Reset the Database

Remove the Postgres volume and restart:

bash
docker compose down -v
docker compose --profile backend up

WARNING

-v removes all named volumes, including pnpm store and node_modules caches. A fresh pnpm install will run on next start.

View Logs for a Single Service

bash
docker compose logs -f api

Rebuild a Specific Service

bash
docker compose build api
docker compose --profile backend up

Shell into a Running Container

bash
docker compose exec api sh

How Dependency Installation Works

Backend services do not install dependencies themselves. A shared pnpm-install init container runs pnpm install --frozen-lockfile once before any app service starts. App services depend on it via condition: service_completed_successfully.

Installed node_modules are persisted in named volumes (root-node-modules, api-node-modules, etc.) so subsequent starts skip the install step unless the lockfile changes.