feat(infra): dockerised full-stack dev mode — apps compose profile (ADR-0030) #258
Reference in New Issue
Block a user
Delete Branch "feat/dockerised-dev-mode"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implements ADR-0030 (now
accepted): a Docker Composeappsprofile that runs the three Nx dev servers (portal-bff,portal-shell,portal-admin) from a sharedDockerfile.dev, so a developer can boot the whole stack with no native Node/pnpm:Purely additive and profile-gated — the native
nx serveflow and the devcontainer are untouched. Dev-only; no production images (those stay with the ADR-0028 Container Registry work).What lands
docs/decisions/0030-dockerised-dev-mode.mdproposed→accepted.docs/decisions/README.mdaccepted.infra/local/Dockerfile.devnode:24-bookworm+ corepack (pnpm resolved frompackageManagerat runtime — no pinned version to drift). No COPY/install at build time.NX_DAEMON=false,NODE_OPTIONS=--max-old-space-size=4096.infra/local/dev-entrypoint.shAPF_ROLE=bff) runsprisma generate+prisma migrate deploythen serves; SPA services go straight tonx serve.infra/local/dev.compose.ymlappsprofile. A one-shotapps-depsservice installs into a sharednode_modulesvolume once (the 3 servers gate on itsservice_completed_successfully, avoiding a 3-way install race);portal-bff/portal-shell/portal-adminservices from the shared image via ax-app-baseanchor. Repo bind-mounted;node_modules+.nxin named volumes.infra/local/dev.shappsadded toALL_PROFILES(so teardown / status / logs catch it) + usage / examples.infra/README.mddocs/setup/01-dev-debian-vm-setup.mdCLAUDE.mdKey design decisions
Dockerfile.dev+ a singlepnpm installserves all three apps.node_modules+.nxin named volumes, not bind-mounted. The container's install (native modules —esbuild,@swc/core, Prisma engines,lmdb,@parcel/watcher— built for this image) must never be shadowed by the host'snode_modules. The repo source is bind-mounted for hot reload; these two directories are overlaid with named volumes.apps-depsone-shot avoids the install race. Three services sharing onenode_modulesvolume can't all runpnpm installconcurrently. A dedicated install service runs first; the three app servicesdepends_onits completion.NX_DAEMON=falsein the containers — three containers sharing one workspace would otherwise contend on the Nx daemon.apps/portal-bff/.env(Entra / session / jwks secrets) viaenv_file: { required: false }; the host-specific URLs (DATABASE_URL/REDIS_URL/ OTel endpoint) are overridden inenvironment:— rebuilt frominfra/local/.envcreds → Compose service names. Composeenvironmentwins overenv_file, so the localhost values in the BFF.envdon't leak into the container.apps/portal-bff/.envmust exist (same as native dev);required: falselets SPA-only devsupwithout it (the BFF then fails its own boot validators with a clear message).Validation on the VM
docker compose -f dev.compose.yml --profile apps configvalidates (YAML, anchors / merge, env interpolation).bash -nclean ondev-entrypoint.shanddev.sh../infra/local/dev.sh up appsbrings up postgres / redis / otel +apps-deps(one-shot, exit 0) + portal-bff / portal-shell / portal-admin, all containers report healthy or running.apps-depspopulates the sharednode_modulesvolume; the three servers reach theirnx servestep without re-installing../infra/local/dev.sh up(noapps) unchanged for native devs.Follow-ups identified during VM validation
http://<vm-ip>:4200/from the workstation surfaces a "Backend unreachable" message: the SPA's hardcodedbffApiBaseUrl: 'http://localhost:3000/api'(ADR-0018 build-time env) plus the BFF'sCORS_ALLOWED_ORIGINS=http://localhost:4200,…both assume "browser on the same machine as the BFF", which doesn't hold here. Fixed in the stacked follow-up PRfeat/spa-dev-proxy(proxy/apiin the Angular dev-server + relativebffApiBaseUrl), which lands right after this PR.environment.otlpEndpoint) and the cross-SPA links (adminAppUrl,shellAppUrl) remain absolute and hit the same remote-browser limit; not blocking for v1, can be revisited if needed.Related
feat/spa-dev-proxy— the SPA-side proxy fix that makes the dockerised mode usable from a remote browser.