Skip to content

Embed IANA timezone database in the binary#21

Open
AevumDecessus wants to merge 1 commit into
anupcshan:mainfrom
AevumDecessus:feat/embed-tzdata
Open

Embed IANA timezone database in the binary#21
AevumDecessus wants to merge 1 commit into
anupcshan:mainfrom
AevumDecessus:feat/embed-tzdata

Conversation

@AevumDecessus
Copy link
Copy Markdown
Contributor

What

The dashboard's schedule view renders current time using time.Now().Hour() and time.Now().Weekday() in cmd/anantha/cmd/templates.go. On minimal container base images (debian:bookworm-slim, distroless, scratch) the IANA zoneinfo files are not present, so Go's runtime falls back to UTC regardless of what the TZ environment variable says. The result is a UTC-rendered schedule grid for users in any other zone, and the notification timestamp formatter at serve.go:1006 (t.Local().Format(...)) is similarly stuck on UTC.

This PR adds a single anonymous import of time/tzdata to cmd/anantha/main.go. That embeds the IANA zone database into the binary at link time. Users still need to set TZ in their environment (e.g. TZ=America/New_York in their compose file or via environment:), but with the embed the lookup succeeds regardless of base image.

Why this approach

Three options were considered:

  • Install tzdata in the Dockerfile: works, ~2.6 MB image growth, but only fixes the official Docker image. Users running anantha natively via go install github.com/anupcshan/anantha/cmd/anantha@latest still see UTC.
  • Embed time/tzdata (this PR): ~400 KB binary growth, fixes both Docker and native install paths, future-proof against base-image churn (Dockerfile could later switch to scratch or distroless without breaking timezones).
  • Both: trivial cost difference, but the embed alone is enough.

The embed-only approach is the minimal change that fixes the broadest set of deployment shapes.

Verification

Built locally with go build and confirmed:

  • Binary size: 22.4 MB -> 22.9 MB (+403 KB / +1.8%).
  • With TZ=America/New_York set, time.LoadLocation("America/New_York") succeeds and renders local hour (9 EDT) vs UTC (13). Without TZ, behavior is unchanged from main (still UTC).
  • All four lint gates pass: go build, go vet, go fmt, golangci-lint (0 issues).

User-facing change

After merging, users who want local-time rendering should set TZ in their environment:

# Native:
TZ=America/New_York anantha serve ...

# Docker compose:
environment:
  - TZ=America/New_York

# Docker run:
docker run -e TZ=America/New_York ... ghcr.io/anupcshan/anantha:latest serve ...

Without TZ set, behavior is identical to today (UTC). No regression for existing deployments.

The dashboard schedule view renders current hour and weekday using time.Now() in the process's local timezone. On minimal container base images (debian:bookworm-slim, distroless, scratch) the IANA zoneinfo files are not present, so Go's runtime falls back to UTC regardless of what the TZ environment variable says. The result is a UTC schedule grid for users in any other zone, and notification timestamps formatted in UTC at serve.go:1006.

Importing time/tzdata embeds the IANA zone database into the binary at link time, so the runtime can resolve any zone name without filesystem zoneinfo. Users still need to set TZ in their environment (e.g. TZ=America/New_York) for the binary to know which zone, but with this import the lookup succeeds regardless of base image.

Binary size impact is approximately 400 KB on a 22 MB starting binary (about 2%). Native go install users benefit identically to docker users.

Verified locally: TZ=America/New_York with the embedded tzdata renders 9:29 EDT for the current moment vs 13:29 UTC, exactly as expected.
AevumDecessus added a commit to AevumDecessus/anantha that referenced this pull request May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant