Post-process adapter-node output into a single self-contained
build/bundle.mjs (614 KB) via esbuild, then ship it on a fresh
alpine:3.21 base with just the node binary copied in. Drops the
node_modules + package manager baggage that comes with node:25-alpine.
- Add esbuild devDep + `bundle` script (scripts/bundle.mjs)
- Dockerfile: drop `deps` stage; final stage is alpine + node binary +
bundle + static client assets
- Uncompressed image: 177 MB -> 149 MB (-16%)
- Verified: /, /healthz, static assets all respond identically;
outbound TLS to api.marktvogt.de works via node's built-in CA bundle
- Replace bun with pnpm (v10.33.0) via corepack
- Upgrade all Docker images from node:22/bun to node:25-alpine
- Update CI pipeline, pre-commit hooks, and prettierignore
- Add packageManager field to package.json for version pinning
- Add PUBLIC_TURNSTILE_SITE_KEY as Docker build arg and Woodpecker CI arg
- Uncomment auth nav in Header and MobileNav (login/logout/profile links)
- Move ThemeToggle from header to footer
- Expand country dropdown from DACH-only to all European countries
- Replace profile route redirect with requireAuth guard
- Set cookie secure flag based on environment (secure in prod)
- Add error handling to admin markets page (403 instead of 500)