Home >
Programming, Servers & Scripts >
Installing And Using The New Maxmind City Location Databases On Your Own Server (46)
07-20-2013 01:07 PM
#1
caurmen (Administrator)
Installing And Using The New Maxmind City Location Databases On Your Own Server
Introduction
So, as you may have heard, MaxMind (the best geolocation service out there) is in the process of changing how they do business. That might mean that, if you're using their Javascript geolocation, things suddenly start costing money or stopping working.
For that and a variety of other reasons, it's probably better to run MaxMind scripts from your own server - but it's also a bit harder to do.
STM to the rescue! Here's a guide to installing the latest MaxMind city and country location database and using it on your own server.
What you'll need
- Command-line (SSH) access to your server. If you don't have that, you can ask your hosts to install the MaxMind GeoLite 2 databases for you - if necessary, feel free to copy/paste the "Installing The Database" section to them.
- PHP 5.3 or greater. If you're on a reasonably modern server, you'll have that - if in doubt, ask your hosting provider.
- Basic familiarity with the Linux command line. You don't need to be a sysadmin god, but you'll need to be able to change directories! If you're not confident about that, ask your hosting provider to do the installation part for you - see "Installing The Database".
What we'll achieve
By the end of this tutorial, you'll have the latest MaxMind databases installed on your own server. That means that:
- Your landing pages will no longer depend on MaxMind's service, meaning that if they decide to shut it down or change it, your profits won't be affected.
- You'll be using the latest database for IP address lookups, which means that more visitors to your LP will have their location correctly identified.
- You'll have more options for locations in your LPs - not just city, but also region and even latitude/longditude.
Step 1: Installing The Database
The installation process for the new
MaxMind PHP database looks complicated, but it's simpler than it looks. Here's the simple way to do it:
1) Log into your server and change directory to the root of your web directories. (That'll be /usr/local/apache2/htdocs by default on Apache servers, and /usr/local/nginx/html or /usr/share/nginx/www for Nginx.)
3) Create a directory called "geolocation" under that directory. Change directory to it.
2) Download the MaxMind database to the directory you just created. (You can actually put it in any directory you like, but I'm recommending this one for simplicity.)
You can either download it
from this page to your local computer, then unzip it and upload it via SFTP/FTP, or you can just go to your SSH client and type
Code:
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
tar zxvf Geolite2-City.mmdb.gz
Note: on some versions of Linux, for an unknown reason, wget won't work to download this file. In that case, just download it onto your home computer, unzip it and upload
3) Change back to your root directory.
4) Now, we need to install Composer, which manages the code libraries for the new GeoIP platform. Run
Code:
curl -sS https://getcomposer.org/installer | php
If it throws any error messages, do what they suggest - they'll usually come with very clear instructions to add a line to a PHP configuration file or similar.
5) Make a file called "composer.json" in the root of your web directory, and paste the following lines into it:
Code:
{
"require": {
"geoip2/geoip2": "0.4.*"
}
}
Now, run
Code:
php composer.phar install
That'll automagically install everything you need for GeoIP!
Step 2: Code For Your Landers
OK, that's the hard bit over with.
To make this detection code work on your landers, just add the following PHP at the start of your landing page:
Code:
<?PHP
require $_SERVER['DOCUMENT_ROOT'].'/vendor/autoload.php';
$ipaddress = $_SERVER["REMOTE_ADDR"];
use \GeoIp2\Database\Reader;
$reader = new Reader($_SERVER['DOCUMENT_ROOT'].'/geolocation/GeoLite2-City.mmdb');
$record = $reader->omni($ipaddress);
?>
That code looks up the visitor's IP address, and compares it against the database to get a whole bunch of useful information.
Now, we can access that information whenever we want.
Displaying user's city
The simplest thing you'll probably want to do is insert the name of the user's city. You can do that adding:
Code:
<?=$record->city->name;?>
wherever you want the city name to be displayed in your landing page.
It's worth knowing that MaxMind sometimes doesn't find a city name, and so displays a blank.
In that case, you can display something else - like "Your City", say - by adding the following code right below the code you added at the start of the landing page:
Code:
<?if ($record->city->name == '') $record->city->name = 'Your City';?>
Other Things You Can Do On Your Landers With This Code
- You can display a user's state, rather than city, by using <?=$record->mostSpecificSubdivision->name;?>
- Or you can display their country using <?=$record->country->name;?>
- You can also do a SWITCH statement or IF statement on their country to, for example, redirect Facebook approvals people to the right page. It's easiest to do this with the country's ISO code ("US", "GB", etc), which you can get with $record->country->isoCode .
- You can get the longditude and latitude of the user with $record->location->longditude or $record->location->latitude. You can use this to get a list of nearby cities - I'll write a tutorial on how to do that soon!
- You can find out how accurate this lookup is likely to be with $record->city->confidence - and if it's below a given value, say 50, you can display a different piece of text or even an entirely different lander!
- You can access city names in other languages using the $record->city->names array. I'll be honest and say I haven't 100% figured out how to do this, but it's possible!
- You can detect if the IP belongs to an anonymous proxy with $record->traits->isAnonymousProxy . Proxied IPs might well be spy accounts, so you could theoretically then redirect them or show them an entirely fake lander!
There's loads of other stuff, too - you can find out ISP name, type of connection, and more. I'm pretty excited about all the new options in this library. It's a bit tricky to wade through, but the
API documentation has all the details.
And that's it! Let me know if you've found this tutorial useful, if you were confused by any points or if they didn't work, or if there's more information or a related tutorial you'd like to see!
07-20-2013 02:35 PM
#2
pain2k (Veteran Member)
If you can afford it there's also netacuity geolocation. It should be more accurate than maxmind.
07-20-2013 04:47 PM
#3
hd2010 (Member)
netacuity geolocation ?
07-20-2013 05:23 PM
#4
pain2k (Veteran Member)
http://info.digitalelement.com/us/
07-20-2013 08:15 PM
#5
rafael (Member)
Awesome tutorial as always caurmen! Thanks!
How does this DB 's accuracy compare the JS include? Same , more or less accurate? I don't remember where but someone here on STM said that it's less accurate.
07-20-2013 10:42 PM
#6
sarsap (Member)
Is there city detection for mobile 3G?
All I can get is the country from maxmind demo
07-26-2013 10:16 PM
#7
alexpte (Member)
Has anyone had any trouble installing the database? I asked beyond hosting to install it to my VPS today and copied them the instructions, but they are having trouble getting it working. Apparently the databases are quite new and there are no instructions for how to install it on cpanel or something? Both the database and composer are in my file system but I'm getting error messages when trying to pull city data.
07-27-2013 03:52 PM
#8
caurmen (Administrator)
@alexpte - it should just be a case of uploading the file. What error messages are you seeing?
@sarsap - I'm not entirely sure about that - interesting question. I suspect it may depend on your carrier - anyone know for sure? (If not I'll look into it!)
@rafael - the accuracy should be greater, because they stopped supporting the JS include in May, wheras this is their newest db.
07-27-2013 10:57 PM
#9
blockis (Member)
I just installed it following this guide. It doesn't take a whole lot of knowledge of Unix, but it really helps (it did for me here).
I noticed a few discrepancies that I had compared to the tut...
- My "web root" was not in that default location (Using Hostgator cPanel VPS). If yours isn't in that location either, use
Code:
cd /
find . -name public_html -type d
where public_html is typically where files are located. - When you download the database, i had to use gunzip to unzip it, it didn't like the z option for me, but maybe that's something with how they set uo the VPS. Anyways, I got it extracted using
Code:
gunzip Geolite2-City.mmdb.gz
- There's an '=' in the PHP city statement, might want to change to [PHP]<? echo $record->city->name; ?>[/PHP]
I've tested it and it's correct for where I am, but I'll need to see how accurate it is. If it's anything like the Javascript version (and I haven't used that for a couple of years) it should do fine for the US...
07-29-2013 09:01 AM
#10
caurmen (Administrator)
@blockis - great tips! Everyone - if you're having trouble, definitely try these.
The PHP statement will work as-is - I'm using the Short Echo Tag syntax. However, your version is more universal - if my version doesn't work because you're on a PHP version below 5.4 with short open tags disabled, your version will work well!
07-30-2013 01:47 AM
#11
blockis (Member)

Originally Posted by
caurmen
@blockis - great tips! Everyone - if you're having trouble, definitely try these.
The PHP statement will work as-is - I'm using the
Short Echo Tag syntax. However, your version is more universal - if my version doesn't work because you're on a PHP version below 5.4 with short open tags disabled, your version will work well!
Interesting -- I had no idea. Learn something new everyday I guess lol.
07-30-2013 11:08 AM
#12
davidal (Member)
For those on Beyondhosting, don't waste your time asking them to install this because they won't do it as it's a beta version. They do have the original Geolite installed on their servers (not sure of the difference), and a little script like this on your webpage will work for you, no installations necessary:
Code:
<?php
// get user's information
$ipInformation = geoip_record_by_name($_SERVER['REMOTE_ADDR']);
// print location
echo "Hello from {$ipInformation['city']}, {$ipInformation['region']}!";
?>
07-30-2013 11:18 AM
#13
caurmen (Administrator)
@davidal - You can actually install it yourself on a BH server if you have SSH access - but if you don't, or if you just want to go a simpler route, the code you posted also works pretty well!
MaxMind say that their new database is significantly more accurate, so probably worth at least testing it if you can, but both options work pretty well.
07-30-2013 11:24 AM
#14
davidal (Member)

Originally Posted by
caurmen
@davidal - You can actually install it yourself on a BH server if you have SSH access - but if you don't, or if you just want to go a simpler route, the code you posted also works pretty well!
MaxMind say that their new database is significantly more accurate, so probably worth at least testing it if you can, but both options work pretty well.
Not gonna lie, I'd have no idea what I was doing if I were to try and install it myself, and I'd probably make a mistake. Can it be done through cpanel?
07-30-2013 12:03 PM
#15
caurmen (Administrator)
Nope, afraid not - it's an SSH or bust deal.
I'd just stick with the BH-installed version - it'll be good enough until MaxMind bring the v2 out of beta.
07-30-2013 02:53 PM
#16
bhmonkey (Member)
Thanks for the share, this is awesome! I've used Maxmind for their fraud stuff before and it is great, but they do charge for it.
07-31-2013 01:39 AM
#17
tmcalvin (Member)
This is what BH replied to me with. I don't have SSH enabled so I figured it would be quicker just to have them do it.
Is their version different?

Originally Posted by
BH
You do not need to use this version.
The server you have already has the php GeoIP module installed and the databases you require.
07-31-2013 04:17 AM
#18
zeno (Administrator)

Originally Posted by
tmcalvin
This is what BH replied to me with. I don't have SSH enabled so I figured it would be quicker just to have them do it.
Is their version different?
GeoIP2 doesn't appear to improve much for an affiliate marketer vs GeoIP legacy (what you, I and most will have). Slightly different data presentation, some improvements like localised place names and such, but overall isn't likely to make calling state out on a lander any more efficient. Stick with what ya got!
07-31-2013 05:55 AM
#19
tmcalvin (Member)

Originally Posted by
zeno
GeoIP2 doesn't appear to improve much for an affiliate marketer vs GeoIP legacy (what you, I and most will have). Slightly different data presentation, some improvements like localised place names and such, but overall isn't likely to make calling state out on a lander any more efficient. Stick with what ya got!
Thanks zeno, I didn't know if the update might help with the issue I've had with sometimes the geo info not displaying.
btw, do you have the code for displaying some alternate text in the case this happens? Like "your city" where the city would go when it fails.
07-31-2013 08:09 AM
#20
zeno (Administrator)
That's easy, you just need to add a line to the PHP code to tell it "if X is empty, then X = Your City". So it will depend on exactly what code you're using. Caurmen's code does that in this part:
[PHP]<?if ($record->city->name == '') $record->city->name = 'Your City';?>[/PHP]
Otherwise something similar to what davidal posted:
[PHP]
<?php
$ipinfo = geoip_record_by_name($_SERVER['REMOTE_ADDR']);
$city = $ipinfo['city'];
$region = $ipinfo['region'];
if (empty($city)){
$city = "Your city";
}
if (empty($region)){
$region = "Your area";
}
?>
In the actual page something like:
<p>Hello from <? echo $city ?>, <? echo $region ?>!</p>
[/PHP]
I tend to write PHP like above without many shortcuts at first just so it's easier to work with things in the html, i.e. echo $city is easier than echo $ipinfo['city'].
08-01-2013 04:02 AM
#21
tmcalvin (Member)
thanks zeno, appreciate it
gotta wonder how many people have been like "nice try fucker" in the botched locations before
08-01-2013 05:23 AM
#22
zeno (Administrator)
Word. I get "Find fuckbuddies in Wellington, NZ" all the time. Who am I, Mr Green? I aint no Wellingtonian =/
AFAIK this happens in NZ a lot because most internet traffic routes through Wellington or Auckland. Google Maps is about the only thing which has consistently pinpointed me in Dunedin over the years (and the 7-8 places I've lived + different ISPs).
08-01-2013 01:07 PM
#23
BeyondHosting-Tyler (Member)
Just letting everyone know, all servers come with geo lite installed, we can install the v2 if your on a VPS but most people are on starter and starter is a form of shared hosting so changes to the main php installation are limited.
Once its out of beta it will be up to date on all of our servers. Stability > Features for this market.
08-01-2013 02:32 PM
#24
caurmen (Administrator)
Google Maps is about the only thing which has consistently pinpointed me in Dunedin over the years
It IS possible to do callouts to the Google geolocation service, which is spooky-accurate, as Zeno mentions - however, it's very heavily rate-limited. 2,500 requests a day maximum, I believe.
08-06-2013 05:46 PM
#25
vsuc99 (Member)
After follow this guild, my Lp show:
omni($ipaddress); ?> city->name;?>
Can't show the city data, which step i'm wrong?
08-07-2013 04:35 PM
#26
caurmen (Administrator)
Can you post the four or five lines of HTML around and including the point where you're trying to use that code? It sounds like there's a syntax error somewhere, which should be fairly easy to spot.
09-12-2013 09:30 AM
#27
prof (Member)
Forgive the novice question but is this the kind of thing you could use to redirect traffic that isn't from the country that qualifies for your offer?
Do people do this to protect their LPs from prying eyes?
09-12-2013 03:38 PM
#28
caurmen (Administrator)
@prof - yes, you can definitely do that. Be careful about approvals, though - people approving your ads and landers don't necessarily come from your target country, and so doing a redirect can sometimes result in your campaign not being approved.
09-20-2013 03:00 PM
#29
archer9 (Member)
For anyone who's using Muse, this just a heads up that this script won't work with it. ie. it breaks your lander layout if you try to embed it. In general, Muse doesn't play nice with PHP. I've played around with this but just can't get the script to work.
09-21-2013 10:58 AM
#30
caurmen (Administrator)
@archer9 - the trick with Muse and PHP is to author your page in Muse, export to HTML, then add the PHP into the page using a text editor. It's a bit of a pain but not too bad.
12-17-2014 10:46 AM
#31
vision (AMC Alumnus)

Originally Posted by
naesm
This is the code I am using to echo the city name. <?php echo $_SERVER['GEOIP_CITY'] . ""; ?> Can anyone help me figure out how to add a default value if there is no city found?
For example if no city is returned echo "Your area"
Code:
<?php
$city = $_SERVER['GEOIP_CITY'];
if (empty($city)) { $city = "Your area"; }
echo $city;
?>
12-17-2014 09:34 PM
#32
naesm (Member)

Originally Posted by
vision
Code:
<?php
$city = $_SERVER['GEOIP_CITY'];
if (empty($city)) { $city = "Your area"; }
echo $city;
?>
Thanks guys this worked perfectly.

FYI, if you are hosting with Storm you can install the Maxmind module for free! They will install it and then all of the calls are available globally on all of your domains. You don't even have to put any scripts on your pages. Only the calls. Here is the list of the available stuff you can do. I'm a terrible coder but managed to hack it together. Ughhh I hate coding......
<?php
echo 'geoIP Address: ' . $_SERVER['GEOIP_ADDR'] . "<br>\n";
echo 'geoIP Area Code: ' . $_SERVER['GEOIP_AREA_CODE'] . "<br>\n";
echo 'geoIP Continent Code: ' . $_SERVER['GEOIP_CONTINENT_CODE'] . "<br>\n";
echo 'geoIP Country Code: ' . $_SERVER['GEOIP_COUNTRY_CODE'] . "<br>\n";
echo 'geoIP Country Name: ' . $_SERVER['GEOIP_COUNTRY_NAME'] . "<br>\n";
echo 'geoIP DMA Code: ' . $_SERVER['GEOIP_DMA_CODE'] . "<br>\n";
echo 'geoIP Latitude: ' . $_SERVER['GEOIP_LATITUDE'] . "<br>\n";
echo 'geoIP Longitude: ' . $_SERVER['GEOIP_LONGITUDE'] . "<br>\n";
echo 'City name: '.$_SERVER['GEOIP_CITY'] . "<br>\n";
echo 'City address: '.$_SERVER['GEOIP_ADDR'] . "<br>\n";
echo 'City region: '.$_SERVER['GEOIP_REGION'] . "<br>\n";
?>
For example, if you want to call the city name and want a default value in case nothing is returned this is how you would do it.
<?php
$city = $_SERVER['GEOIP_CITY'];
if (empty($city)) { $city = "Your Area"; }
echo $city;
?>
03-03-2015 11:54 AM
#33
artsifin (Member)
Hey!
Couple of very noob questions...
I'm hosting my site at Amazon S3. I downloaded Python and S3 Express, but I haven't got a clue on what I'm doing. How do I get access to the S3 with SSH in the first place? I'm at Mac.
And another question... I just got the MaxMind GeoIP thingy for 50 000 queries. Is it necessary to install the DB, or can I somehow use the API key or something?
More specifically, I'm trying to get the map lander from Caurmen to work properly.
Thanks! 
03-03-2015 01:46 PM
#34
Deckerd (Member)
Has anyone tested the AnyonymousProxy functionality? I set it up on my site and saw web proxies still getting through. I had to setup their minFraud system to accurately flag down proxies, but it costs $.005/query, which flat isn't afforable on many campaigns.
I had someone else set it up, so there's a chance there was some error in the code. What are your experiences?
06-06-2015 05:05 PM
#35
wiifmdude ()
Well I've installed it and all I can't say is that you better NOT count on it too much in EU, most tests I've done through a VPN gave me nada for the city (e.g. tested FR, NL = zero city/region, US OK).
06-14-2015 04:34 PM
#36
zeno (Administrator)

Originally Posted by
wiifmdude
Well I've installed it and all I can't say is that you better NOT count on it too much in EU, most tests I've done through a VPN gave me nada for the city (e.g. tested FR, NL = zero city/region, US OK).
This isn't necessarily bad - remember that VPN services are quite different to real users, they are usually in a data center somewhere which may not have residential ISP traffic going through it.
07-09-2015 09:01 PM
#37
pain2k (Veteran Member)
Hey guys,
Any code for the ISP database as well detecting proxy and redirecting if true?
Thanks!
07-10-2015 10:32 AM
#38
caurmen (Administrator)
@pain2k - For detect and redirect proxy:
<?if ($record->traits->isAnonymousProxy == ''TRUE") header('Location: http://www.example.com/');?>
should work. It'll redirect to whatever location you put in place of http://www.example.com .
For checking the ISP, there's sample code to do that on MaxMind's PI docs site - http://maxmind.github.io/GeoIP2-php/ - here's the code from there:
Code:
<?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/GeoIP2-ISP.mmdb');
$record = $reader->isp('128.101.101.101');
print($record->autonomousSystemNumber . "\n"); // 217
print($record->autonomousSystemOrganization . "\n"); // 'University of Minnesota'
print($record->isp . "\n"); // 'University of Minnesota'
Hope that helps!
07-10-2015 11:54 AM
#39
pain2k (Veteran Member)
Awesome thanks!!
07-21-2015 01:04 PM
#40
thesussexfox (Member)
Hi Guys,
I've just uploaded the STM mobile tracker to a subdomain on my VPS - I've purchased the GeoIP2 ISP Database but it's downloaded as a zip file with 2 CSV files and not a DAT file as expected - would you know how to get this working as i cant find any threads fro this?
Any help would be appreciated
Michael
07-21-2015 02:09 PM
#41
pain2k (Veteran Member)
Download the binary file instead.
07-21-2015 02:17 PM
#42
thesussexfox (Member)
OFFS - I didnt even consider that - what a tit. Thanks mate
11-07-2015 05:22 PM
#43
gohardgary (AMC Alumnus)
I just tried setting up Maxmind on a new domain and I get this error message:
"Fatal error: Class 'MaxMind\Db\Reader' not found in /home/perfectmatch/public_html/vendor/geoip2/geoip2/src/GeoIp2/Database/Reader.php on line 57"
Is anyone here familiar with this?
11-07-2015 05:30 PM
#44
Adamw (AMC Alumnus)

Originally Posted by
gohardgary
I just tried setting up Maxmind on a new domain and I get this error message:
"Fatal error: Class 'MaxMind\Db\Reader' not found in /home/perfectmatch/public_html/vendor/geoip2/geoip2/src/GeoIp2/Database/Reader.php on line 57"
Is anyone here familiar with this?
When you navigate to this directory (/home/perfectmatch/public_html/vendor/geoip2/geoip2/src/GeoIp2/Database/) on your server... do you see the Reader.php file?
11-07-2015 06:11 PM
#45
gohardgary (AMC Alumnus)

Originally Posted by
Adamw
When you navigate to this directory (/home/perfectmatch/public_html/vendor/geoip2/geoip2/src/GeoIp2/Database/) on your server... do you see the Reader.php file?
Yes, the Reader.php file is there.
11-08-2015 12:25 PM
#46
Adamw (AMC Alumnus)

Originally Posted by
gohardgary
Yes, the Reader.php file is there.
pm'd... easier to figure out over skype
Home >
Programming, Servers & Scripts >