How to Install the Maxmind GeoIP2 Database and PHP API

A couple of years ago I posted “Blazing Geo Lookups! How To Install Maxmind PHP Extension on Your Server” which detailed how to get the Maxmind’s GeoIP database setup on your server.

Since then, Maxmind has updated their database format to “GeoIP2”.  This new format is supposed to be better/faster, etc. Sounds great. But the new format also requires a different method of setup.

Unfortunately, the documentation on how to get this set up from start to finish is still non-existent.

While going through this set up process myself, I ran into a handful of problems. Most of them were small, but some required a lot of searching and trying different things to figure out what was wrong.  To help you avoid the same issues, I decided to create this walk-through and note any problems you might have.

What’s in the box

At the end of this walk-through, you’ll have:

(1) The latest GeoLite2-City db installed
(2) The latest PHP API installed
(3) The optional PHP C Extension installed
(4) A feeling of warm satisfaction and accomplishment

Note: These install instructions are for Centos 6.5  Final.  They should work for other Centos versions.   You’ll also probably be able to follow this guide on Ubuntu as well.  But some commands like “yum” will need to be changed.

I. Installing the Database

First up, let’s download the latest GeoLite2-City database.   Open up your Putty SSH Client (see: “Affiliate’s Guide to SSH – Part 1“) and login to your server.

Note: For the purposes of this tutorial, my working directory will be “/root”.

The database is a bit hard to find, but here is the download page. http://dev.maxmind.com/geoip/geoip2/geolite2/

We want theGeoLite2 City Maxmind DB.  (Not the CSV).    If you hover over the link, you can right-click and “Copy Link Location”.

Now that we’ve got the URL, we can use wget to download it to our server, unzip it, and move it to the proper directory.  Here are the commands do just that.

Note: Rather than blindly copying & pasting these lines, I encourage you to spend a moment to think about what you’re doing.  Being familiar with the command line is a good thing 😉

wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
gunzip GeoLite2-City.mmdb.gz
mkdir /usr/local/share/GeoIP
mv GeoLite2-City.mmdb /usr/local/share/GeoIP/

 

The database is now installed, but we can’t really make any use of it until we install an API.

II. Installing the PHP API

Since we’ll be using our database with PHP, we’re going to be using the PHP API.  The API is available through Composer.  Composer is “dependency manager” (i.e. package manager) for PHP.    To use Composer you first need to install it.  So we’ll be using the instructions I found here: https://getcomposer.org/doc/00-intro.md#installation-nix

In your terminal run:

curl -sS https://getcomposer.org/installer | php

This will download “composer.phar” to your working directory. (Whatever directory you’re currently in).

Here’s a screenshot of my Putty session.

2014-04-17_1300

You can see I get the message “Composer successfully installed to /root/composer.phar”  — it’s telling me where it put this .phar file.

OK so now it’s time to use Composer to grab the geoip2 package.  (See: https://packagist.org/packages/geoip2/geoip2   and https://github.com/maxmind/GeoIP2-php)

We need to create a .json file that tells Composer what we want to install. So back to the terminal:

vi composer.json

Type i (To “Insert”).  Then paste this:

{
    "require": {
    "geoip2/geoip2": "0.6.*"
    }
}

Then type :wq (That’s colon+w+q) To save the file.

There will now be a new .json file in your working directory. Now, back in the shell, execute this command:

php composer.phar install

If all goes well, Composer will grab all the stuff we need.

In my case, things did not go smoothly. I received this message:

Loading composer repositories with package information
Installing dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
– maxmind-db/reader v0.3.0 requires ext-bcmath * -> the requested PHP extension bcmath is missing from your system.
– geoip2/geoip2 v0.6.0 requires maxmind-db/reader 0.3.* -> satisfiable by maxmind-db/reader[v0.3.0].
– Installation request for geoip2/geoip2 0.6.* -> satisfiable by geoip2/geoip2[v0.6.0].

Composer is complaining that “bcmath” is not installed. To fix that is pretty simple:

yum install php-bcmath

Trying the composer install command, it now works. Yay!

You should now see there is a new directory called “vendor”. This is where all of that stuff was installed to. Here’s a screenshot of what you should see.

2014-04-17_1319

If you run the sample code now, Geo lookups should work and everything should be peachy.

If you’re happy with slow Geo lookups you can stop here and skip to section VI.

But I want FAST Geo lookups. So I’ll need to install the PHP C Extension. You should want FAST Geo lookups too! 😉

III. Install C Library for Maxmind DB Format

The PHP C Extension requires the use of the C Library. (Remember I said this could be confusing?)

Have no fear, you can just keep following along.

Note: For reference purposes This page details some directions on how to do this https://github.com/maxmind/MaxMind-DB-Reader-php also https://github.com/maxmind/libmaxminddb

It may be tempting to just download the Master.zip from Github but that did not work for me. Instead I needed to use Git to clone the repository. Nothing else seemed to work.

First, make sure Git is installed and do this:

yum install git

Now we can use git to clone the repository.

git clone --recursive https://github.com/maxmind/libmaxminddb

Now run the following commands:

Note: Pay close attention to the output after you run ./configure and make check. The system will issue warnings and errors if it encounters a problem. For example I got error regarding “libtool”. To fix it I had to run “yum install libtool” before running ./bootstrap again.

cd libmaxminddb
./bootstrap
./configure
make check
sudo make install
sudo ldconfig

If all goes well, the C Library for the Maxmind DB format is now installed. We can now (finally) install the PHP C Extension.

IV. Install PHP C Extension

To install the PHP extension we need to navigate to a directory inside your vendor directory. So (assuming you’re in /root) do this:

cd /root/vendor/maxmind-db/reader

Now execute the following commands:

Note: if you get “Command not found” after you run “phpize” you need to install PHP Developer tools. Do this: yum install php-devel — then try phpize again.

cd ext
phpize
./configure
make
make test
make install

You should get a message like on 64-bit systems:

Installing shared extensions:     /usr/lib64/php/modules/

or this on 32-bit systems:

Installing shared extensions:     /usr/lib/php/modules/

The path where your extensions are installed may be different. That’s OK.

V. Configuring the PHP Extension

Now that our PHP Extension is installed we need to tell PHP it’s available. Create a PHP file called “phpinfo.php” somewhere in your web directory with this contents:

<?php
phpinfo();
?>

Now visit the page in your browser. You should see a PHP info page. About 7 rows down you’ll see where it says “Loaded Configuration File” and next to it a path like this:

2014-04-21_1518

That’s the file we need to edit. (Your path will likely be different.) So back in the shell:

nano /etc/php.ini

Once inside the Nano editor, scroll all the way to the bottom and add this new line:

extension=maxminddb.so

CTRL-O then Enter to Save.
CTRL-X to exit

Now we need to update the dynamic links for libmaxminddb. Not knowing I need to do this step had me banging my head against the wall for quite some time. Thankfully I found this post: https://github.com/maxmind/MaxMind-DB-Reader-php/issues/7 Thanks to the guy who took the time to post that solution!

Do this:

ldconfig /usr/local/lib

Now we need to restart Apache so PHP “picks up” this new configuration.

service httpd restart

Now refresh that phpinfo.php page in your browser. If you scroll down the page, under Configuration you’ll see extensions in alphabetical order. If all went well, you’ll see the maxminddb extension there too!

2014-04-21_1503

VI. Testing

All that’s left is to test everything.

Up until now, our “vendor/” directory has been sitting in root. We need to move or copy it to our www folder so we can use it in our projects or landing pages. We can copy it like this:

cp -r /root/vendor var/www/maxmind

Note: Your destination directory will be different. So change /var/www to wherever you want to copy too. e.g. /home/{username}/www/maxmind

Create a new file called “test.php” the “maxmind” directory and paste in this example code: (from https://github.com/maxmind/GeoIP2-php):

<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

// This creates the Reader object, which should be reused across
// lookups.
$reader = new Reader('/usr/local/share/GeoIP/GeoLite2-City.mmdb');

// Replace "city" with the appropriate method for your database, e.g.,
// "country".
$record = $reader->city('128.101.101.101');

print($record->country->isoCode . "\n"); // 'US'
print($record->country->name . "\n"); // 'United States'
print($record->country->names['zh-CN'] . "\n"); // '美国'

print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'

print($record->city->name . "\n"); // 'Minneapolis'

print($record->postal->code . "\n"); // '55455'

print($record->location->latitude . "\n"); // 44.9733
print($record->location->longitude . "\n"); // -93.2323
?>

If you visit the page in your browser you should see some output that shows that the IP on line 11 is located in Minneapolis.

You can modify this to show a users IP dynamically like this:

$record = $reader->city( $_SERVER['REMOTE_ADDR'] );

Conclusion

Phew. This post took forever to create, so if you found it useful please drop me a line below. Also retweets are welcome 😉

I should note that you can use this setup with the paid “GeoIP2” database as well. All you need to do is change the database filename in line 7 above to “GeoIP2-City.mmdb”.

Also, while this focuses on using the PHP API, there are many other APIs offered by Maxmind. The Apache Module was intriguing but it only allows you to do lookups for current visitors IP. For my purposes this was a deal breaker. But if that’s all you want to do, you might want to have a look at that. It may be simpler to install and simpler to use.

And finally… there are a lot of steps to this– that means quite a few things can go wrong along the way. If you run into problems, go back and check your work– you may have mistyped something. If that doesn’t help, try contacting your web host. 90% of this is server configuration so those are the guys to bug if this doesn’t work. You can simply link to my post here and they should be able to follow this quite easily.

Cheers!

Leave a comment

*


*

CommentLuv badge

31 Comments

  • before i found this article, I have problem to use maxmind. after i found this article, now I can use it.many thanks for this tutorial.. this is use full..

    • You’re welcome! Thanks for taking the time to comment.

  • Seriously?! Nobody could think of even more complicated method to install GeoIP2? There can be issues on every step… Unbelievable…

    • But it all worked fine… apart some compiler packages missing. Thanks

    • Unfortunately lots of server packages turn out this way. They are designed to be modular and work with a variety of setups. In there lies the complexity.

      Glad you were able to get this working. Thanks for commenting.!

  • So, I installed it (except the C library and the PHP C Extension) on my local linux machine and it works just fine. If I just copy and paste the files to my hosting provider, and fix the paths of the database will it work? Great article by the way. Thanks!

    • Hi yeah copying and pasting to your host may work. But if I were you I’d just work through the steps again. It would be safer and guaranteed.

      Thanks for reading and taking the time to comment!

  • Awesome blog. Thanks a ton.

  • THANK YOU for this post. I was waiting for a simple “hey, `phpize` comes in ___” in the MaxMind docs and just couldn’t find it. Your post was perfect. Surprising how simple this extension was to compile!

    • Glad you found the post useful. Thanks for letting me know!

  • I’d like to say, thank you very much
    You don’t know how much this article help me
    People like you makes the difference
    🙂

  • jacuna

    You are my newest best friend! I’m writing from Argentina. Found your tutorial on Google. And after a couple o little problems get finally to work! Thank you very much 🙂

    • Thanks for letting me know it helped you. Cheers!

  • Thank you so much! It’s been a few years since I’ve set up Maxmind and was struggling with the new setup. Your tutorial saved me several hours of screaming and monitor punching.

    • LOL glad it helped. Thanks for letting me know.

  • Jay

    Thanks for this guide! It was absolutely helpful!

    • Thanks for letting me know it helped. Cheers!

  • Ammoula

    hello,i can’t see any output 🙁

  • Ray

    Hello. Excellent tutorial. Everything is ok, except I cannot install C Library. I have an issue with the repisotiry.

    Resolving deltas: 100% (2401/2401), done.
    Submodule ‘t/libtap’ (git://github.com/zorgnax/libtap.git) registered for path ‘t/libtap’
    Submodule ‘t/maxmind-db’ (git://github.com/maxmind/MaxMind-DB.git) registered for path ‘t/maxmind-db’
    Initialized empty Git repository in /home/offshore-website/csv/vendor/libmaxminddb/t/libtap/.git/
    github.com[0: 192.30.252.129]: errno=Connection timed out
    fatal: unable to connect a socket (Connection timed out)
    Clone of ‘git://github.com/zorgnax/libtap.git’ into submodule path ‘t/libtap’ failed

    So, I had to use the slow solution. This one is running. Do you have a solution for this issue?
    Thanks in advance

    • Looks like some kind of connection problem. Sorry this is probably a good question for your hosting company support team.

    • Jim

      Use “git config –global url.”https://”.insteadOf git://” your firewall is blocking git://

  • Troop

    Hi, Thank you very much for this post. It was very helpful!

  • Anton

    Hi! This post is awesome.

    Tip: If you encounter any of these errors while trying to compile PHP extension:
    > error: maxminddb.h: No such file or directory
    > cannot find -lmaxminddb
    then simply run
    $ ./configure CXXFLAGS=”-I/usr/local/include/ -L/usr/local/lib/”
    instead of just
    $ ./configure

    In my case required files were located as follows:
    /usr/local/include/maxminddb.h
    /usr/local/lib/libmaxminddb.so

  • Ameer Elsherif

    First of all thanks for the great tutorial.
    And second of all, I’ve followed your instructions and successfully installed the extension on PHP v5.4 but, now I’ve upgraded to v5.6 and the extension is gone!
    I’ve tried to repeat the steps of the extension installing section but nothing changed.
    Is there anything special I’m supposed to do??

  • Jim

    Thanks for this well written tutorial!

  • Ananth

    Nicely explained!
    Yes this will do the work for you. Just follow the steps carefully. This one worked. I am glad.
    many thanks to ‘ctrtard’. You are awesome

  • Daniel

    Doesn’t work.

    To install GeoIP2 I had to install Guzzle. Maybe that has something to do with it.

  • RanG

    Do you have the steps to install geoIp for mmdb database in apache?

Trackbacks/Pingbacks

[…] This is the lesson from the forum I referred to about installing the Maxmind DB for geo lookups. […]

How to Install the Maxmind GeoIP2 Database and PHP API [Link] « November 30, 2014

[…] If you are hesitating to use it on web server section, or you are prefer to use a PHP library to call the functions, please feel free to read the decent guide here http://ctrtard.com/code/how-to-install-the-maxmind-geoip2-database-for-php/. […]

How to Install the Maxmind GeoIP2 Database and PHP API [Link] « May 11, 2015

 
 
 

Related posts by category

Related posts by tag