dorfteich/deploy/compose/compose.dev.yml
Claude Opus 4.8 8316c617d2
All checks were successful
CD / Build and push images (push) Successful in 2m36s
CI / Lint, typecheck, test (push) Successful in 1m50s
CI / Auth e2e pack (push) Successful in 1m58s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m13s
CD / Promote to Int (push) Successful in 11s
Add collaboration server skeleton (Hocuspocus) with health, container, and CI/CD (#33)
Bootstrap apps/collab as a Hocuspocus WebSocket server (ADR 0003):
- pino JSON logging (service=collab) and shared Zod env validation
  (collabEnvSchema); structured connection open/close logs.
- /healthz endpoint (process liveness + PostgreSQL ping) served via the
  onRequest hook, matching the container-internal path and the proxied
  /collab/healthz path; any WebSocket handshake is accepted for now
  (authentication arrives with #34, persistence with #35).
- Dockerfile (ESM workspace build) and a compose service on the frontend
  and internal networks with a healthcheck; dev overlay service and a new
  COLLAB_PORT variable.
- CD builds, pushes, and promotes the collab image; CI builds it on PRs;
  the smoke suite asserts /collab/healthz through the reverse proxy.
- deployment.md/stages.md: proxy routing, per-stage COLLAB_PORT, checklist.

Closes #33

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 14:53:44 +02:00

99 lines
3.5 KiB
YAML

# Development overlay: hot-reloading web and api containers with the
# repository mounted, layered over the production stack definition.
#
# Full containerized dev environment (first start installs dependencies):
# cd deploy/compose && cp .env.example .env
# docker compose -f docker-compose.yml -f compose.dev.yml up
# → web http://localhost:5173, api http://localhost:3001, db localhost:5434
#
# Database-only (run web/api natively for the fastest feedback):
# docker compose -f docker-compose.yml -f compose.dev.yml up -d db
# DATABASE_URL=postgresql://dorfteich:dorfteich@localhost:5434/dorfteich \
# PORT=3001 pnpm --filter @dorfteich/api start:dev
# pnpm --filter @dorfteich/web dev
services:
web:
image: node:22.15-alpine
build: !reset null
working_dir: /repo
command: sh -c "npm i -g pnpm@11 && pnpm install && pnpm --filter @dorfteich/web dev -- --host 0.0.0.0"
environment:
VITE_API_PROXY_TARGET: http://api:3000
ports: !override
- '127.0.0.1:5173:5173'
volumes:
- ../..:/repo
# Container-local node_modules: the host directories contain
# macOS binaries and must not leak into the Linux containers.
- web-root-modules:/repo/node_modules
- web-app-modules:/repo/apps/web/node_modules
- shared-modules:/repo/packages/shared/node_modules
- pnpm-store:/root/.local/share/pnpm/store
depends_on: !reset []
api:
image: node:22.15-alpine
build: !reset null
working_dir: /repo
command: sh -c "npm i -g pnpm@11 && pnpm install && pnpm --filter @dorfteich/shared build && pnpm --filter @dorfteich/api start:dev"
environment:
NODE_ENV: development
PORT: '3000'
DATABASE_URL: postgresql://dorfteich:${POSTGRES_PASSWORD:-dorfteich}@db:5432/dorfteich
ports: !override
- '127.0.0.1:3001:3000'
volumes:
- ../..:/repo
- api-root-modules:/repo/node_modules
- api-app-modules:/repo/apps/api/node_modules
- api-shared-modules:/repo/packages/shared/node_modules
- pnpm-store:/root/.local/share/pnpm/store
collab:
image: node:22.15-alpine
build: !reset null
working_dir: /repo
command: sh -c "npm i -g pnpm@11 && pnpm install && pnpm --filter @dorfteich/shared build && pnpm --filter @dorfteich/collab start:dev"
environment:
NODE_ENV: development
PORT: '3000'
DATABASE_URL: postgresql://dorfteich:${POSTGRES_PASSWORD:-dorfteich}@db:5432/dorfteich
ports: !override
- '127.0.0.1:3002:3000'
volumes:
- ../..:/repo
- collab-root-modules:/repo/node_modules
- collab-app-modules:/repo/apps/collab/node_modules
- collab-shared-modules:/repo/packages/shared/node_modules
- pnpm-store:/root/.local/share/pnpm/store
# No healthcheck block here: the production image's HEALTHCHECK does not
# apply to this node:alpine dev image, and nothing depends on it.
healthcheck: !reset null
db:
ports:
# 5434 on the host to avoid colliding with other local PostgreSQL
# instances (5432 system, 5433 wochenplan-staging).
- '127.0.0.1:5434:5432'
# Local SMTP catcher: UI on http://localhost:8025, SMTP on 1025 —
# matches the api's SMTP_* defaults.
mailpit:
image: axllent/mailpit:latest
ports:
- '127.0.0.1:1025:1025'
- '127.0.0.1:8025:8025'
volumes:
web-root-modules:
web-app-modules:
shared-modules:
api-root-modules:
api-app-modules:
api-shared-modules:
collab-root-modules:
collab-app-modules:
collab-shared-modules:
pnpm-store: