Alexandr Semin 942f94b34a Устойчивость к сбоям и атомарное обновление баз
- update.sh: set -e -> set -u, сетевой сбой больше не роняет контейнер
- curl с --retry, неудачный цикл пропускается и повторяется на INTERVAL
- три базы применяются только после успеха всех загрузок (нет частичного обновления)
- парс версии терпит пробелы, удалён дублирующий resolve_url
- Dockerfile: non-root user geoip, HEALTHCHECK по всем трём .mmdb
- README: секция про правильный watcher, перевод на русский (README.ru.md)
2026-07-03 05:19:16 +03:00

geoip-worker

Container for periodic MaxMind GeoIP database updates (ASN, Country, City).

Usage

docker-compose

volumes:
  geoip-data:

services:
  geoip-worker:
    image: git.rus-anonym.xyz/public/geoip-worker:latest
    volumes:
      - geoip-data:/data
    restart: unless-stopped

  your-service:
    image: ...
    volumes:
      - geoip-data:/geoip:ro

Databases will be available at /geoip:

  • /geoip/asn.mmdb
  • /geoip/country.mmdb
  • /geoip/city.mmdb

Environment variables

Variable Default Description
DATA_DIR /data Directory for storing .mmdb files
INTERVAL 43200 Update check interval in seconds (12 hours)

Behavior

  • On startup, immediately checks for updates and downloads databases if needed
  • Repeats the check every INTERVAL seconds
  • Current database version is stored in DATA_DIR/.version
  • Files are updated atomically (via .tmp -> rename)
  • All three databases are committed only after every download succeeds; a partial failure leaves the existing files untouched
  • Network errors are retried and never crash the container; a failed cycle is skipped and retried on the next INTERVAL

Watching for updates in your service

Databases are replaced atomically with rename(), which creates a new inode each time. This has consequences for how you watch and read them:

  • Watch the directory, not the individual files. An inotify watch on a single .mmdb path (or IN_MODIFY) tracks the old inode and will miss the swap. Watch /geoip for IN_MOVED_TO / IN_CREATE instead (most fsnotify / watchdog-style libraries do this when you watch a folder).
  • Prefer watching .version as the single trigger. It is written last, after all three databases are in place. Reacting to a .version change avoids the brief window where the three files are swapped one by one, and gives you a single consistent "update complete" signal. On that event, reopen all three databases.
  • Reopen the file on change. Readers like libmaxminddb mmap() the file. A rename() does not affect an already-open fd or mapping, so you must reopen / re-mmap the database to see new data. Mapping once at startup will never pick up updates.
  • Cross-container watching over a shared Docker volume works: inotify events propagate because both containers share the same host kernel and filesystem.
S
Description
No description provided
Readme
32 KiB
Languages
Shell 83.1%
Dockerfile 16.9%