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
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.
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
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.
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 poolingAnd then execute:
bundle installIf your app is behind Cloudflare, setup is super simple:
-
Enable IP Geolocation in Cloudflare
-
That's it! No initializer needed. Just use it:
# In your controller
Trackdown.locate(request.remote_ip, request: request).country
# => 'United States'If you want to use trackdown with a MaxMind database as the geo IP data provider:
- Run the generator:
rails generate trackdown:installThis will create an initializer file at config/initializers/trackdown.rb. Open this file and add your MaxMind license key and account ID next.
- 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)
endTip
To get your MaxMind account ID and license key, you need to create an account at MaxMind and get a license key.
- Download the database:
Trackdown.update_databaseYou 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- 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/PacificNote
MaxMind updates their databases every Tuesday and Friday.
# In your controller - pass the request object
result = Trackdown.locate(request.remote_ip, request: request)
result.country
# => 'United States'To geolocate an IP address:
# Works anywhere - just needs the IP
result = Trackdown.locate('8.8.8.8')
result.country
# => 'United States'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` gemFor 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'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: { ... }
# }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
endTrackdown.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.
endOnly needed when using the MaxMind provider:
Trackdown.update_databaseWhen 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.
Downloads the GeoLite2-City database to your server and performs local lookups using connection pooling for performance.
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.
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.
The gem is available as open source under the terms of the MIT License.