Appearance
Deployment
Docker Compose (Development)
yaml
# docker-compose.yml
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: planner
POSTGRES_USER: planner
POSTGRES_PASSWORD: planner
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
backend:
build:
context: .
dockerfile: docker/Dockerfile.backend
ports:
- "4000:4000"
depends_on:
- db
environment:
DATABASE_URL: postgresql://planner:planner@db:5432/planner?schema=public
frontend:
build:
context: .
dockerfile: docker/Dockerfile.frontend
ports:
- "3000:3000"
depends_on:
- backend
website:
build:
context: .
dockerfile: docker/Dockerfile.website
ports:
- "8080:8080"
docs:
build:
context: .
dockerfile: docker/Dockerfile.docs
ports:
- "8081:8080"
volumes:
pgdata:Production Deployment
bash
docker compose -f docker-compose.prod.yml up -dThe production compose file uses optimized Dockerfiles (Dockerfile.backend.prod) with multi-stage builds for smaller images.
Dockerfiles
All Dockerfiles are based on node:22-alpine with consistent stage naming:
| Stage | Description |
|---|---|
base | Base Node image |
deps | Install dependencies |
dev | Development mode |
builder | Build the app |
runner | Production runtime |
Backend Dockerfile (docker/Dockerfile.backend)
dockerfile
FROM node:22-alpine AS base
# ... standard pnpm setup with corepack
WORKDIR /app
FROM base AS deps
COPY pnpm-lock.yaml package.json pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
FROM base AS dev
COPY --from=deps /app/node_modules ./node_modules
COPY . .
CMD ["sh", "-c", "cd apps/backend && pnpm dev"]Environment Variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | postgresql://planner:planner@localhost:5432/planner | PostgreSQL connection |
JWT_SECRET | (required) | Secret for access tokens |
JWT_REFRESH_SECRET | (required) | Secret for refresh tokens |
UPLOAD_DIR | ./uploads | File upload directory |
Port Mapping
| Service | Internal Port | External Port |
|---|---|---|
| Backend | 4000 | 4000 |
| Frontend | 3000 | 3000 |
| Website | 8080 | 8080 |
| Docs | 8080 | 8081 |
| PostgreSQL | 5432 | 5432 |
Health Check
All services respond with HTTP 200 when running:
bash
curl http://localhost:4000/api/health
curl http://localhost:3000
curl http://localhost:8080
curl http://localhost:8081