The image was on node:22-alpine while CI pins node-version: 20 and
package.json declares engines.node >=20.0.0. Align all three stages
so the container builds and runs on the same major the project is
tested against.
Give forkers who self-host on their own infra a first-class container
path instead of hand-rolling a Dockerfile and guessing the Next.js
standalone wiring.
- Multi-stage Dockerfile (deps -> build -> runtime) using Next.js
output: "standalone"; runs as a non-root user.
- Single-service docker-compose.yml — Supabase stays external, so no
database container is included.
- .dockerignore and docs/docker.md documenting the setup, including the
build-time (NEXT_PUBLIC_*, inlined into the client bundle) vs runtime
(server secrets via env_file) split.
- Set output: "standalone" in next.config.ts. This is a no-op for
next start and the Hostinger path; only the Docker build consumes it.
Purely additive: no dependency or stack changes, existing deploy paths
are unaffected. Database migrations remain out of scope for the
container (applied via the Supabase CLI, matching the external-Supabase
model).