Skip to content

rameerez/trackdown

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

52 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ trackdown - Ruby gem to geolocate IPs

trackdown is a Ruby gem that allows you to geolocate IP addresses easily. It works out-of-the-box with Cloudflare (zero config!); and it's also a simple, convenient wrapper on top of MaxMind (just bring your own MaxMind key, and you're good to go!). trackdown offers a clean API for Rails applications to fetch country, city, and emoji flag information for any IP address.

Given an IP, it gives you the corresponding:

  • πŸ—ΊοΈ Country (two-letter country code + country name)
  • πŸ“ City
  • πŸ‡ΊπŸ‡Έ Emoji flag of the country

Two ways to use trackdown

Option 1: Cloudflare (recommended, zero config)

If your app is behind Cloudflare, you can use trackdown with zero configuration:

  • No API keys needed
  • No database downloads
  • No external dependencies
  • Instant lookups from Cloudflare headers

Just enable "IP Geolocation" in your Cloudflare dashboard and you're done! We automatically check for the Cloudflare headers in the context of a request and provide you with the IP geo data.

Option 2: MaxMind (BYOK - Bring Your Own Key)

For apps not behind Cloudflare, offline apps, non-Rails apps, or as a fallback, use MaxMind:

  • Requires MaxMind account and license key
  • Requires downloading and maintaining a local database
  • Works offline once database is downloaded
  • Get started at MaxMind

Option 3: Auto

By default, trackdown uses :auto mode which tries Cloudflare first and falls back to MaxMind automatically.

Note

Trackdown fails gracefully. If no provider is available (no Cloudflare headers, no MaxMind database), it returns 'Unknown' instead of raising an error, so your app doesn't crash due to a missing geolocation provider.

Installation

Add this line to your application's Gemfile:

gem 'trackdown'

# Optional: Only needed if using MaxMind provider
gem 'maxmind-db'        # For MaxMind database access
gem 'connection_pool'   # For connection pooling

And then execute:

bundle install

Setup

Quick Start (Cloudflare)

If your app is behind Cloudflare, setup is super simple:

  1. Enable IP Geolocation in Cloudflare

  2. That's it! No initializer needed. Just use it:

# In your controller
Trackdown.locate(request.remote_ip, request: request).country
# => 'United States'

Setup with MaxMind

If you want to use trackdown with a MaxMind database as the geo IP data provider:

  1. Run the generator:
rails generate trackdown:install

This will create an initializer file at config/initializers/trackdown.rb. Open this file and add your MaxMind license key and account ID next.

  1. Configure your MaxMind credentials in config/initializers/trackdown.rb:
Trackdown.configure do |config|
  config.provider = :auto  # or :maxmind to use MaxMind exclusively

  # Use Rails credentials (recommended)
  config.maxmind_account_id = Rails.application.credentials.dig(:maxmind, :account_id)
  config.maxmind_license_key = Rails.application.credentials.dig(:maxmind, :license_key)
end

Tip

To get your MaxMind account ID and license key, you need to create an account at MaxMind and get a license key.

  1. Download the database:
Trackdown.update_database

You can configure the path where the MaxMind database will be stored. By default, it will be stored at db/GeoLite2-City.mmdb:

config.database_path = Rails.root.join('db', 'GeoLite2-City.mmdb').to_s
  1. Schedule regular updates (optional but recommended):

The trackdown gem generator creates a TrackdownDatabaseRefreshJob job for regularly updating the MaxMind database. You can just get a database the first time and just keep using it, but the information will get outdated and some IPs will become stale or inaccurate.

To keep your IP geolocation accurate, you need to make sure the TrackdownDatabaseRefreshJob runs regularly. How you do that, exactly, depends on the queueing system you're using.

If you're using solid_queue (the Rails 8 default), you can easily add it to your schedule in the config/recurring.yml file like this:

production:
  refresh_trackdown_database:
    class: TrackdownDatabaseRefreshJob
    queue: default
    schedule: every Saturday at 4am US/Pacific

Note

MaxMind updates their databases every Tuesday and Friday.

Usage

With Cloudflare (recommended when available)

# In your controller - pass the request object
result = Trackdown.locate(request.remote_ip, request: request)
result.country
# => 'United States'

With MaxMind or without request object

To geolocate an IP address:

# Works anywhere - just needs the IP
result = Trackdown.locate('8.8.8.8')
result.country
# => 'United States'

API Methods

You can do things like:

Trackdown.locate('8.8.8.8').emoji
# => 'πŸ‡ΊπŸ‡Έ'

In fact, there are a few methods you can use:

result.country_code    # => 'US'
result.country_name    # => 'United States'
result.country         # => 'United States' (alias for country_name)
result.city            # => 'Mountain View' (from MaxMind or Cloudflare's "Add visitor location headers")
result.flag_emoji      # => 'πŸ‡ΊπŸ‡Έ'
result.emoji           # => 'πŸ‡ΊπŸ‡Έ' (alias for flag_emoji)
result.country_flag    # => 'πŸ‡ΊπŸ‡Έ' (alias for flag_emoji)
result.country_info    # => # Rich country data from the `countries` gem

Rich country information

For country_info we're leveraging the countries gem, so you get a lot of information about the country, like the continent, the region, the languages spoken, the currency, and more:

result.country_info.alpha3          # => "USA"
result.country_info.currency_code   # => "USD"
result.country_info.continent       # => 'North America'
result.country_info.nationality     # => 'American'
result.country_info.iso_long_name   # => 'The United States of America'

Hash data

If you prefer, you can also get all the information as a hash:

result.to_h
# => {
#      country_code: 'US',
#      country_name: 'United States',
#      city: 'Mountain View',
#      flag_emoji: 'πŸ‡ΊπŸ‡Έ',
#      country_info: { ... }
#    }

Configuration

Provider Options

Trackdown.configure do |config|
  # :auto - Try Cloudflare first, fall back to MaxMind (default, recommended)
  # :cloudflare - Only use Cloudflare headers
  # :maxmind - Only use MaxMind database
  config.provider = :auto
end

Full Configuration Example

Trackdown.configure do |config|
  # Provider
  config.provider = :auto

  # MaxMind settings (only needed if using MaxMind)
  config.maxmind_account_id = Rails.application.credentials.dig(:maxmind, :account_id)
  config.maxmind_license_key = Rails.application.credentials.dig(:maxmind, :license_key)
  config.database_path = Rails.root.join('db', 'GeoLite2-City.mmdb').to_s

  # Performance tuning (MaxMind only - requires maxmind-db gem)
  config.timeout = 3
  config.pool_size = 5
  config.pool_timeout = 3
  # config.memory_mode = MaxMind::DB::MODE_MEMORY  # or MODE_FILE to reduce memory

  # General
  config.reject_private_ips = true  # Reject 192.168.x.x, 127.0.0.1, etc.
end

Updating the MaxMind database

Only needed when using the MaxMind provider:

Trackdown.update_database

How It Works

Cloudflare Provider

When you enable "IP Geolocation" in Cloudflare, they add the CF-IPCountry header to every request. If you enable "Add visitor location headers" (via Managed Transforms), you also get CF-IPCity.

Trackdown reads these headers directly from the request with zero overhead, and no database lookups.

MaxMind Provider

Downloads the GeoLite2-City database to your server and performs local lookups using connection pooling for performance.

Development

After checking out the repo, run bundle install to install dependencies. Then, run bundle exec rake test to run the Minitest tests.

To install this gem onto your local machine, run bundle exec rake install.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/trackdown. Our code of conduct is: just be nice and make your mom proud of what you do and post online.

License

The gem is available as open source under the terms of the MIT License.