Lightweight IP geolocation service using MaxMind GeoLite2 database.
- Fast IP-to-location lookups (city, country, continent, coordinates)
- Request queuing with configurable concurrency control
- Simple API key authentication
- Comprehensive integration test suite
- Docker-ready with automatic MaxMind database downloads
- Built with Hono and Bun for performance
- Copy environment file:
cp .env.example .env- Set your configuration in
.env:
API_KEY=your-secret-api-key
GEOIP_ACCOUNT_ID=your-maxmind-account-id
GEOIP_LICENSE_KEY=your-maxmind-license-key- Install dependencies:
bun install- Download MaxMind database manually (first time):
# Get a free account at https://www.maxmind.com/en/geolite2/signup
# Download GeoLite2-City.mmdb and place it at /usr/share/GeoIP/GeoLite2-City.mmdb
# Or set GEOIP_DB_PATH in .env to your local path- Start development server:
bun devBuild and run:
docker build -t geo-service .
docker run -p 3000:3000 \
-e API_KEY=your-secret-api-key \
-e GEOIP_ACCOUNT_ID=your-account-id \
-e GEOIP_LICENSE_KEY=your-license-key \
geo-serviceThe container will automatically download the MaxMind database on first start.
curl http://localhost:3000/Response:
{
"status": "ok",
"service": "geo-service",
"version": "1.0.1",
"uptime": 3600,
"timestamp": "2026-06-07T12:00:00.000Z",
"database": {
"path": "/usr/share/GeoIP/GeoLite2-City.mmdb",
"lastModified": "2026-06-01T00:00:00.000Z"
},
"queue": {
"pending": 0,
"size": 0,
"isPaused": false
},
"endpoints": {
"health": "GET /",
"lookup": "GET /lookup/:ip (requires X-API-Key header)"
}
}curl -H "X-API-Key: your-secret-api-key" \
http://localhost:3000/lookup/8.8.8.8Response:
{
"continent": {
"geonameId": 6255149,
"name": "North America"
},
"country": {
"geonameId": 6252001,
"name": "United States"
},
"city": {
"geonameId": 5375480,
"name": "Mountain View"
},
"location": {
"accuracyRadius": 1000,
"latitude": 37.386,
"longitude": -122.0838,
"timeZone": "America/Los_Angeles"
}
}| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 3000 |
Server port |
API_KEY |
Yes | - | API authentication key |
QUEUE_CONCURRENCY |
No | 2 |
Max concurrent MaxMind lookups |
GEOIP_DB_PATH |
No | /usr/share/GeoIP/GeoLite2-City.mmdb |
Path to MaxMind database file |
GEOIP_ACCOUNT_ID |
Yes | - | MaxMind account ID for database downloads |
GEOIP_LICENSE_KEY |
Yes | - | MaxMind license key for database downloads |
{
"error": "Missing X-API-Key header"
}{
"error": "Invalid API key"
}{
"error": "Invalid IP address format"
}{
"error": "Location not found for IP"
}bun testbun run lint # Check for issues
bun run lint:fix # Auto-fix issuesbun run build # Output to dist/- Generate a secure API key:
uuidgen -7-
Set environment variables in your deployment platform
-
Deploy the Docker container or build the service:
bun run build
bun run dist/index.jsThis project includes GitHub Actions workflows for:
- CI Pipeline: Runs linting, tests, and build on PRs and pushes to main
- Docker Build: Builds and pushes Docker images to GitHub Container Registry
- Dependabot: Automated dependency updates
Status badges are shown at the top of this README.