Skip to content

Adds geo-ip-service database updates from MaxMind - #3

Merged
jim-toth merged 1 commit into
masterfrom
geo-ip-database-updates
Oct 15, 2026
Merged

jim-toth merged 1 commit into
masterfrom
geo-ip-database-updates

Conversation

@jim-toth

Copy link
Copy Markdown
Contributor

Summary

geo-ip-service now downloads the GeoLite2 databases from MaxMind and keeps them current without a restart, while contacting MaxMind as little as possible: only when a database on the volume is missing or past its age, and never more often than a minimum interval that holds across restarts. Every part of the cycle can be exercised in seconds against a stub, and against MaxMind on demand with a one-shot command.

Changes

  • Updates run on a schedule (GEOIP_CHECK_INTERVAL, default 1h). An edition is due when it is not loaded or its build is older than GEOIP_MAX_AGE (default 72h), and the last request to MaxMind for it was at least MAXMIND_MIN_REQUEST_INTERVAL ago (default 12h). Checking whether anything is due makes no request.
  • An update fetches the published checksum first and stops there when it matches the installed archive. Otherwise it downloads the archive and:
    • checks it against the checksum
    • extracts the .mmdb
    • checks the edition and that the build is not older than the loaded one
    • writes the file beside the current one, renames it into place, and swaps the reader with no failed lookups
  • Any failure leaves the current file and database serving.
  • Credentials (MAXMIND_ACCOUNT_ID, MAXMIND_LICENSE_KEY) are read as secrets and sent only in the Authorization header to MaxMind, never to the host it redirects downloads to. Without them the service never contacts MaxMind and only loads files from disk.
  • Each attempt's time, outcome, error and archive checksum are kept per edition in update-state.json on the data volume, which is what holds the request interval across restarts.
  • SIGHUP reloads the databases from disk without contacting MaxMind.
  • src/update.ts runs one forced update with the same code, into the data directory or --dir, exiting 1 on failure, for checking credentials and the real download path right away.
  • /healthz shows each edition's update record and its next check. /metrics adds whether updates are on, the last attempt time, and attempts by edition and outcome.
  • A small MaxMind stub serves the test databases as archives with the checksum file, auth and redirect. Tests set it up per scenario, and it runs standalone for local update cycles.
  • service-kit gains env.durationMs for settings such as 30s, 12h or 3d.
  • The service README covers the update rules, settings, reload, the one-shot command and testing updates locally.

Verified

  • bun run check under Bun 1.4.3: typecheck clean, 103 tests pass. The update tests cover:
    • first start on an empty volume
    • no requests after a restart with current files
    • a checksum-only check when nothing is new
    • the request interval holding across restarts
    • a new release swapped in during a lookup loop with no failed lookups
    • forced updates
    • eight failure scenarios that each keep the installed database: refused credentials, rate limiting, server error, unreachable, checksum mismatch, archive without the database, wrong edition, corrupt database
    • refusing an older build
    • credentials never sent past the redirect
    • the license key redacted even when the server repeats it
    • an unreadable record file
  • Ran the service against the standalone stub with a one-second schedule: it downloaded both editions on an empty volume, then made checksum-only checks at the configured interval. /healthz and /metrics showed each attempt. A restart with files on the volume made no requests. SIGHUP reloaded from disk.
  • Ran the one-shot command against the stub: exit 0 with the right credentials, 1 with a wrong key or incomplete credentials.
  • Built the image: the one-shot command is in it. Without credentials it reports updates off and makes no request. podman stop exits 0.
  • Not yet run against MaxMind itself; that needs the account ID and license key and is one run of the one-shot command.

…p, persisted request interval, SIGHUP reload, one-shot update command and download stub
@jim-toth
jim-toth merged commit 7198cd1 into master Oct 15, 2026
6 checks passed
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