master
- update.sh: set -e -> set -u, сетевой сбой больше не роняет контейнер - curl с --retry, неудачный цикл пропускается и повторяется на INTERVAL - три базы применяются только после успеха всех загрузок (нет частичного обновления) - парс версии терпит пробелы, удалён дублирующий resolve_url - Dockerfile: non-root user geoip, HEALTHCHECK по всем трём .mmdb - README: секция про правильный watcher, перевод на русский (README.ru.md)
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
INTERVALseconds - 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
.mmdbpath (orIN_MODIFY) tracks the old inode and will miss the swap. Watch/geoipforIN_MOVED_TO/IN_CREATEinstead (mostfsnotify/watchdog-style libraries do this when you watch a folder). - Prefer watching
.versionas the single trigger. It is written last, after all three databases are in place. Reacting to a.versionchange 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
libmaxminddbmmap()the file. Arename()does not affect an already-open fd or mapping, so you must reopen / re-mmapthe 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.
Languages
Shell
83.1%
Dockerfile
16.9%