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.
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.
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).