.dockerignore excluded .git/, so `git rev-parse --short HEAD` inside the
Dockerfile build silently fell back to "unknown" and /healthz reported
`version: unknown` on every deploy. Remove the .git entry; the Dockerfile
already runs git inside the build stage and Dokploy clones --depth 1.
After deploy, `curl https://projax.msbls.de/healthz | tail -1` returns
the short commit SHA matching `git rev-parse --short HEAD` on main —
deploy verification becomes a one-shot SHA match instead of inspecting
container task IDs on mlake.
- Multi-stage Dockerfile: golang:1.25-alpine builder → distroless static
runtime as nonroot. Image weighs ~15 MB. Embeds templates, static
assets and migrations into the single binary.
- deploy/dokploy.yaml documents the Dokploy app for projax.msbls.de:
Tailscale-only, healthz path, single replica, secret PROJAX_DB_URL.
Translates to the Dokploy UI; not auto-applied.
- README rewritten as runbook: env vars, route table, test command,
deploy notes, trust model (Tailscale + no auth in v1, defer to
Supabase auth if it ever outgrows the fence), schema summary.
- .dockerignore strips .git, .m, .claude, docs, tests from build ctx.
- .gitignore covers ad-hoc binary and dist artefacts.
Verified locally: docker build succeeds, container responds to /healthz
and / against msupabase via --network host.