Skip to the content.

Docker

Local Compose stand-ins for local (SQLite), development (Postgres), and test (DynamoDB Local + Lambda RIE). The optional admin Compose profile adds MinIO (local CDN) and @tgmc/admin on port 4400 — not AWS CloudFront.

Operations (commands, ports, troubleshooting): docker/README.md

CI/CD matrix: cicd.md

Host .output

Compose reads workspace .output/<sysEnv> and does not rebuild Nuxt inside the image on every up. scripts/docker-compose.mjs maps:

Stack SYS_ENV Compose file Image copy
local local docker/docker-compose.local.yml Dockerfile.app .output/local
dev development docker/docker-compose.dev.yml Dockerfile.app .output/development (api + web)
test test docker/docker-compose.test.yml Dockerfile.lambda .output/test/server

On build / --build, ensureNitroOutput runs first (SYS_ENV=… npm run build only if server/index.mjs is missing, then prune sharp + .npmrc). Linux images install native deps. .dockerignore allows .output/local|development|test.

Stacks

Stack Compose file SYS_ENV Data App ports
Local docker/docker-compose.local.yml local SQLite (./data volume) web 4200
Development docker/docker-compose.dev.yml development PostgreSQL web 4200, api 4100
Local Lambda test docker/docker-compose.test.yml test DynamoDB Local :8000 lambda-proxy 4300

Port 4200 is shared by host npm run dev, docker:local, and docker:dev — run only one of those at a time.

Hostnames: local → tgmc-portfolio.local; docker:dev → tgmc-portfolio.test (avoid *.dev — HSTS-preloaded). Map both to 127.0.0.1. See ssl-setup.md.

Commands (repo root)

npm run docker:build:local
npm run docker:local          # SQLite via ./data; exclusive with docker:dev on :4200
npm run docker:local:down

npm run docker:build:dev
npm run docker:dev
npm run docker:dev:down

npm run docker:build:test     # ensureNitroOutput(test) then Lambda image
npm run docker:test
npm run docker:test:down

Docker-only admin (standalone stack)

Blog, contact messages, and a local MinIO CDN stand-in. One admin UI with a database selector (sqlite postgres dynamodb). Not part of the public @tgmc/web app.
cp .env.admin.example .env.admin   # set ADMIN_TOKEN
npm run docker:admin
npm run docker:admin:down

Open http://127.0.0.1:4400/admin. See docs/web/features/admin.md.

npm run sam:build is still required to stage infra/sam/.aws-sam/build-src for SAM deploys; Compose test images copy .output/test directly.

Docker ↔ AWS

Concern Compose local Compose dev Compose test AWS SAM
Data SQLite ./data Postgres DynamoDB Local DynamoDB tables
App Nitro node-server Nitro node-server (web + api) Nitro aws_lambda + RIE Lambda + HTTP API
Assets Served by web Served by web Staged only (infra/sam/.aws-sam/build-src/public) Private S3 + CloudFront

Images: Node 24 bookworm. Local/dev web/api share docker/Dockerfile.app (COPY .output/${SYS_ENV}/app/.output). HEALTHCHECK --start-period is a literal 30s (BuildKit does not expand ARG there). Compose healthchecks use HTTPS curl -fkS when HTTPS=1.