diff --git a/.env.example b/.env.example index 77d1bee..889d7c4 100644 --- a/.env.example +++ b/.env.example @@ -100,6 +100,13 @@ DISCORD_REDIRECT_URI= # # Unset falls back to the host's /etc/timezone, which is a real zone whenever # the host clock is set to local time. Set this when the host runs UTC — a UTC -# server is exactly the case that fails. Only the browser sidecar reads it; -# the backend keeps its UTC clock. +# server is exactly the case that fails. Only the browser sidecar reads it — +# the backend's own zone is API_TZ below, and is cosmetic. # BROWSER_TZ=Asia/Jakarta + +# Zone the backend stamps its log lines in. Cosmetic only — it exists so the +# API's logs read on the same clock as the browser sidecar's. Nothing else in +# the service has a zone: bookmark timestamps are unix ms, and the two real +# time columns are timestamptz. Defaults to Asia/Jakarta; set to UTC for the +# conventional server default. +# API_TZ=Asia/Jakarta diff --git a/docker-compose.yml b/docker-compose.yml index eb124f4..ed7f514 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,13 @@ services: # comes from .env so it is never committed. DATABASE_URL: ${DATABASE_URL:-postgres://bookmarks:${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}@postgres:5432/bookmarks?sslmode=disable} PORT: "8080" + # Log timestamps only. Go's `log` stamps lines in local time, and this + # service has no other use for a zone: bookmark timestamps are unix ms + # and the two real time columns are timestamptz, both absolute instants. + # Purely so these lines read on the same clock as the sidecar's. Named + # API_TZ rather than TZ so an operator's exported shell TZ cannot leak + # in; distroless already carries tzdata, so the name just resolves. + TZ: ${API_TZ:-Asia/Jakarta} # Discord OAuth for the browser UI (ADR-0002). The first four are # required; DISCORD_REQUIRED_ROLE is optional and empty by default. # Guild membership is the whole gate: any member becomes a Reader.