Over a million developers have joined DZone.

Using NGINX With GeoIP MaxMind Database to Fetch Geolocation Data

DZone's Guide to

Using NGINX With GeoIP MaxMind Database to Fetch Geolocation Data

Learn how to find the geographical location of a user using their IP address by just configuring NGINX with GeoIP MaxMind databases — without doing ANY coding!

Free Resource

Learn how to create flexible schemas in a relational database using SQL for JSON.

Geolocation data plays a significant role in businesses. This data is used to promote or market brands, products, and services to certain demographics. It also helps in enhancing the user profile.

In this blog, we'll discuss finding the geographical location of a user using their IP address by just configuring NGINX with GeoIP MaxMind databases and without doing any coding!

NGINX, an open-source HTTP and IMAP/POP3 proxy server, is used as a main web server software or reverse proxy server for Apache. Its GeoIP module (ngx_http_geoip_module) uses precompiled MaxMind databases to set variables such as $geoip_country_name$geoip_country_code$geoip_city , and so on with values depending on the client’s IP address.


  • Ubuntu platform (Ubuntu 16.04, 12.04, 11.04).

Use Case

Install NGINX on Ubuntu, configure NGINX with GeoIP MaxMind Databases, and find the geolocation of the user using IP address.


  • Installation and configuration.
  • Fetching geolocation data using client IP.

Installation and Configuration

Let's look at installing and configuring NGINX on Ubuntu, installing the GeoIP module, downloading the GeoIP MaxMind GeoCity and GeoCountry databases, and configuring NGINX with GeoIP MaxMind databases.

Installing and Configuring Nginx on Ubuntu

To install and configure NGINX on Ubuntu, perform the following.

Install NGINX team package signing key using the following command:

$ curl -s https://nginx.org/keys/nginx_signing.key | sudo apt-key add –

Add the repo to your apt sources using the following commands:

$ sudo echo -e "deb https://nginx.org/packages/mainline/ubuntu/ `lsb_release -cs` nginx\n deb-src https://nginx.org/packages/mainline/ubuntu/ `lsb_release -cs` nginx" > /etc/apt/sources.list.d/nginx.list

Resynchronize and install the package index files using the following commands:

$ sudo apt-get update
$ sudo apt-get install nginx

Installing the GeoIP Module

The GeoIP module is used to look up the IP address of a client machine connected to a server machine.

To install the GeoIP module, perform the following steps.

Download and load the module to /usr/lib/nginx/modules using the following commands:

$ sudo add-apt-repository ppa:nginx/stable
$ sudo apt-get update
$ sudo apt-get install nginx-module-geoip

Open nginx.conf using the following command:

$ sudo nano /etc/nginx/nginx.conf

Add the below main context in the nginx.conf file:

load_module "modules/ngx_http_geoip_module.so";

Note: Skip the above steps if --with-http-geoip-module already exists on your version of NGINX.

To check the existence of the GeoIP module, use the below command:

$ nginx -V

Downloading GeoIP MaxMind GeoCity and GeoCountry Databases

To download and extract MaxMind GeoCity and GeoCountry databases in the Ubuntu system, use the following commands:

mkdir - p / etc / nginx / geoip
cd / etc / nginx / geoip
wget http: //geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoI.dat.gz
 gunzip GeoIP.dat.gz
http: //geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
 gunzip GeoLiteCity.dat.gz

Configuring NGINX With GeoIP MaxMind Databases

NGINX is configured with GeoIP MaxMind GeoCity and GeoCountry Databases to access MaxMind geo-variables.

To configure NGINX with the databases, use the below command:

load_module "modules/ngx_http_geoip_module.so";
worker_processes 1;
events {
 worker_connections 1024;
http {
 geoip_country / etc / nginx / geoip / GeoIP.dat;#
 the country IP database
 geoip_city / etc / nginx / geoip / GeoLiteCity.dat;#
 the city IP database
 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 '$status $body_bytes_sent "$http_referer" '
 '"$http_user_agent" "$http_x_forwarded_for"';
 access_log /
  var / log / nginx / access.log main;#
 Set Geo variables in proxy headers
 proxy_set_header X_COUNTRY_CODE $geoip_country_code;
 proxy_set_header X_CITY_COUNTRY_CODE $geoip_city_country_code;
 proxy_set_header X_REGION $geoip_region;
 proxy_set_header X_CITY $geoip_city;
 proxy_set_header X_POSTAL_CODE $geoip_postal_code;
 server {
  listen 80;#
  All other traffic gets proxied right on through.
  location / {
   proxy_pass http: //;

Fetching Geolocation Data Using Client IP

A sample web application (NodeJS application) is created to return requested header parameters via JSON response. Custom geo-fields are added to the requested header and are made accessible from the application. The application is reverse proxied via NGINX.

To get geolocation data of the user, use the following code written in Node.js:

// This sample web application returns request headers in response
 const express = require('express')
 const app = express()
 var count = 1;

// Location "/show_my_identity" hosts the incoming request headers in response in JSON format
 app.get('/show_my_identity', function (req, res) {
 console.log('Request',count++,'received from country : ',req.headers.x_country_code);

// Default "/" message
 app.get('/', function (req, res) {
 res.send("Welcome to Treselle lab");

// Application listening on port 3000
 app.listen(3000, function () {
 console.log('Treselle Lab - App listening on port 3000!')

The output of the application with the geolocation data looks similar to this:select

Note: To run the sample Node.js application, Node.js should be installed with the required modules.

The application log with the geolocation data looks similar to this:select

And that's it!

Create flexible schemas using dynamic columns for semi-structured data. Learn how.

database ,nginx ,geolocation ,tutorial ,maxmind

Published at DZone with permission of Rathnadevi Manivannan. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}