Files
atomic-design-poc/docker-compose.yml
T
ehoandClaude Opus 5 2aa343f255 chore: cap container memory in docker compose
The API container used server garbage collection. Server GC makes one heap per
CPU, which is 22 heaps on this host. The two frontend containers sized the Node
heap from host RAM (16 GB), because compose sets no cgroup limit.

Set DOTNET_gcServer=0 and NODE_OPTIONS=--max-old-space-size=2048. This bounds
the memory that `docker compose up` needs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 22:39:40 +02:00

82 lines
3.7 KiB
YAML

# ponytail: dev-server images (not multi-stage prod builds) — this is a demo.
# `docker compose up` → SSP at http://localhost:4200, behandelportal at :4201 (both LOCALIZED:
# nl at /, en at /en/; the SSP's header language switcher + dev `⚙ state` panel stay visible),
# Swagger at :5000/swagger (one shared backend, WP-67). Each web container does a one-time
# `ng build --configuration development --localize` (development config keeps isDevMode()=true
# so the dev tools render) then serves both locale bundles statically (with /api proxied); for a
# fast HMR loop use `npm start` / `npm run start:behandelportal` locally instead (nl at /).
services:
api:
image: mcr.microsoft.com/dotnet/sdk:10.0
working_dir: /src
command: dotnet run --project src/BigRegister.Api --urls http://+:5000
environment:
- ASPNETCORE_ENVIRONMENT=Development
# ponytail: Server GC makes one heap per CPU (22 here); workstation GC makes one.
- DOTNET_gcServer=0
volumes:
# ':z' relabels for SELinux (Fedora/RHEL); harmless on other hosts.
# WP-22: no separate volume needed for the SQLite file — `dotnet run` sets
# its cwd to the project dir (src/BigRegister.Api), which this bind mount
# already covers, so bigregister.db lands on the host and survives
# `docker compose restart api` / `down` + `up` for free (gitignored).
- ./backend:/src:z
- api-bin:/src/src/BigRegister.Api/bin
- api-obj:/src/src/BigRegister.Api/obj
# WP-25: LetterHtml.Render inlines public/letter.css (the FE⇄BE letter
# contract, repo-root sibling of backend/) — mounted here so the same
# walk-up-from-the-assembly lookup that works for `dotnet run`/tests also
# resolves inside this container, whose bind mount otherwise only sees backend/.
- ./public:/src/public:z
ports:
- '5000:5000'
web:
# slim (Debian/glibc, ~220MB vs ~1.1GB for the full tag): the container only runs
# `npm ci && ng serve`, and the native deps (esbuild, lmdb, @parcel/watcher,
# msgpackr-extract) ship prebuilt glibc binaries, so no build toolchain is needed.
image: node:24-slim
working_dir: /app
# Uses the committed generated client (no codegen at startup). Builds BOTH locale bundles
# once (`ng build --localize`) then serves them statically via scripts/serve-i18n.mjs
# (per-locale SPA fallback + /api reverse-proxy → the api container), so the language
# switcher actually switches. ponytail: `--no-fund --loglevel=error` silences npm 11 noise.
command: sh -c "npm ci --no-fund --loglevel=error && npx ng build ssp --configuration development --localize && node scripts/serve-i18n.mjs"
environment:
# ponytail: without a cgroup limit Node sizes its heap from host RAM (16 GB).
- NODE_OPTIONS=--max-old-space-size=2048
- PORT=4200
- API_PROXY_TARGET=http://api:5000
- APP_DIST_ROOT=dist/ssp/browser
volumes:
- ./:/app:z
- web-modules:/app/node_modules
ports:
- '4200:4200'
depends_on:
- api
web-behandelportal:
image: node:24-slim
working_dir: /app
command: sh -c "npm ci --no-fund --loglevel=error && npx ng build behandelportal --configuration development --localize && node scripts/serve-i18n.mjs"
environment:
# ponytail: without a cgroup limit Node sizes its heap from host RAM (16 GB).
- NODE_OPTIONS=--max-old-space-size=2048
- PORT=4201
- API_PROXY_TARGET=http://api:5000
- APP_DIST_ROOT=dist/behandelportal/browser
volumes:
- ./:/app:z
- web-behandelportal-modules:/app/node_modules
ports:
- '4201:4201'
depends_on:
- api
volumes:
api-bin:
api-obj:
web-modules:
web-behandelportal-modules: