Add optional Docker / Docker Compose support - #372
Conversation
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).
|
Great, well-documented addition — the multi-stage standalone Dockerfile is textbook: running as non-root and keeping server secrets out of the image (build args limited to A couple of things before merge:
None of these affect the default happy path. Thanks for making self-hosting first-class! |
ArnasDon
left a comment
There was a problem hiding this comment.
Comment added in the main thread.
Setting PORT in .env.local moved the port the server listens on *inside* the container (env_file injects it), while the mapping and the healthcheck stayed on 3000 — so the container came up unreachable. The published port is now HOST_PORT, and PORT is pinned to 3000 via `environment` (which takes precedence over env_file) so a leftover PORT in .env.local can no longer desync the app from the mapping. Documented both, including for the plain-docker path.
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.
docs/automations-and-cron.md was never written. Replace the pointer with the details it was standing in for: both cron endpoints, the x-cron-secret header, and the 503 they return until AUTOMATION_CRON_SECRET is set.
|
Thanks for the careful read — all three are pushed, one commit each. 1. Verified with both Container reports healthy. The plain 2. Node parity. All three stages are on 3. Dead doc link. Two things worth flagging:
One last thing — CI on this branch is sitting at |
Summary
Add an optional, self-contained container setup (Dockerfile + Docker Compose) for forkers who self-host on their own infra. Purely additive —
next startand the Hostinger path are unchanged.What changed
Dockerfile— multi-stage (deps → build → runtime) using Next.jsoutput: "standalone"; runs as a non-root user; only.next/standalone,.next/static, andpublicland in the final image.docker-compose.yml— singleappservice. Supabase stays external (no DB container).NEXT_PUBLIC_*are forwarded as build args; server secrets come from.env.localviaenv_fileat runtime. Includes a healthcheck andrestart: unless-stopped..dockerignore— excludes.git,node_modules,.next,docs,supabase, all.env*, etc.docs/docker.md— usage guide, including the build-time (NEXT_PUBLIC_*, inlined into the client bundle) vs runtime (secrets) distinction and the--env-file .env.localnote.next.config.ts—output: "standalone". No-op fornext start/ Hostinger; only the Docker build consumes it.README.md— one line pointing todocs/docker.mdafter the quick start.Database migrations remain out of scope for the container (applied via the Supabase CLI, matching the existing external-Supabase model).
Test plan
npm run typecheckclean.npm run buildsucceeds (runs inside the Docker build).docker compose --env-file .env.local up --build -dbuilds and starts; container reports healthy;/→ 307/dashboard,/login→ 200.Note: the 5 local test failures in
currency/date-utilsare timezone/ICU-locale artifacts of a non-UTC dev machine and are unrelated to this change (the only source edit isoutput: "standalone"); they pass in CI (Linux/UTC).Related
Closes #371.