Following is a quick set of instructions to set up city-level location detection using Maxmind’s GeoIP library using Apache/PHP.

There’re multiple ways to do it. Frankly the trickiest part is figuring-out the most appropriate one. I think the most efficient approach in cost/performance terms is to install C API and then let mod_geoip Apache module interface with it, getting parsed values as part of the $_SERVER variable on the PHP side. There’re some wrapper PHP libraries on top of C library, as well as pure-PHP libraries, but the former did not really work, while the latter is supposed to be much slower than C lib/mod_geoip.

So here we go:

Install GeoIP C API

$ mkdir ~/src
$ cd src
$ wget
$ tar xzvf GeoIP.tar.gz 
$ cd GeoIP-1.4.8
$ ./configure 
$ make
$ sudo make install

Install Apache GeoIP module

$ cd ..
$ wget
$ tar xzvf mod_geoip2_1.2.7.tar.gz 
$ cd mod_geoip2_1.2.7
$ sudo /usr/sbin/apxs -i -a -L/usr/local/lib -I/usr/local/include -lGeoIP -c mod_geoip.c

At the very end, you should get an output like:

[activating module `geoip' in /etc/httpd/conf/httpd.conf]

Please note the Apache config file’s path and in that file, after the LoadModule instruction for geoip (which installation steps above will add automatically) add the following instruction:

<IfModule mod_geoip.c>
   GeoIPEnable On
   GeoIPScanProxyHeaders On
   GeoIPDBFile /usr/local/share/geoip/GeoIP.dat
   GeoIPDBFile /usr/local/share/geoip/GeoLiteCity.dat

Now, let’s download the binary database (.dat) files indicated in the config in those locations:

$ cd /usr/local/share
$ mkdir geoip
$ cd geoip
$ wget
$ gunzip GeoIP.dat.gz
$ wget
$ gunzip GeoLiteCity.dat.gz 

Once you are done setting up, restart Apache and configure a test script to inspect the contents of the new $_SERVER variable, you should see output like:

    [GEOIP_COUNTRY_NAME] => United States
    [GEOIP_REGION_NAME] => Virginia

I put “#CENSORED#” for some values, but obviously there should be actual values present that you can use in your PHP app.

I believe that there’re instructions on the web for installing and configuring similar setup for Nginx and Light HTTPD as well. Approach should be very similar.