Bash Script to Copy Maxmind Databases to WordPress Uploads

My previous tutorial explained how to install MaxMind Geoipupdate on CentOS Linux with a weekly cronjob to update each database. This tutorial introduces a Bash script to copy MaxMind databases to your server’s WordPress websites. There, custom WordPress functions or plugins can access them in the /uploads folder.

Bash Script to Copy Files

Intended Audience: Novice – Intermediate Linux User
Example Linux OS: CentOS 7.x (Adjust commands accordingly)

First, let’s create a basic Bash script. I highly suggest putting this script in a custom location. Do not put executable scripts in website root folders. In fact, don’t put them website folders at all if you can help it.

Instead, create a /scripts/custom-scripts folder. Others prefer /opt or /usr/local/bin. See this page for a comprehensive discussion. Location may matter depending on what system variables and paths you need for other scripts.

First, go to your scripts folder.

]# cd /scripts/custom-scripts

Next, create a new file using vim, nano, or another editor of your choice.

]# vi geoipupdate-weekly

Tip: Remember the file name for the cronjob!

Now, copy+paste the following. Carefully review the commands and comments. Customize any paths and commands to your system.

#!/bin/bash

# Run geoipupdate first. Saves updated .mmdb files to /usr/share/GeoIP folder.
# Include full path or else the commands won't fire on the Cronjob.

/usr/bin/geoipupdate -v

# The path to each website's folder will be similar.
# The difference will be either a domain name, web name, or number, like web1.
# This varies depending on your Linux OS and control panel.
# Put each unique folder name in webarray

webarray=(
wordpress1.com
wordpress2.com
wordpress3.com
)

# Loop through each webarray value
for WEB in "${webarray[@]}"
do

# Important - Customize your destination folder path. It may not match the example.
# Public_html is your web root folder on Cpanel. It might be www, web, or html on another system.
# /wp-content/uploads should be the same on most servers.
DESTFOLDER=/var/www/sites/$WEB/public_html/wp-content/uploads

echo Copying Maxmind files to $DESTFOLDER

# Use cp command to copy each GeoIP database.
# Make sure to include -f (force) to overwrite an old database.
# Remove any unnecessary cp commands from this example, or add more.

/usr/bin/cp -f /usr/share/GeoIP/GeoLite2-City.mmdb $DESTFOLDER
/usr/bin/cp -f /usr/share/GeoIP/GeoLite2-ASN.mmdb $DESTFOLDER
/usr/bin/cp -f /usr/share/GeoIP/GeoLite2-Country.mmdb $DESTFOLDER
/usr/bin/cp -f /usr/share/GeoIP/GeoIP2-Country.mmdb $DESTFOLDER

done

echo All Done
exit

Give Root Permission to Run the Script

We’ll add the cronjob to root’s crontab. That means root must be able to run the script. Give root access to the script.

]# chmod 0755 geoipupdate-weekly

Bash Script Cronjob

Notice the script includes the geoipupdate -v command. We’ll need to update the Cronjob suggested in the last tutorial. Now, we’ll modify the crontab to run our script, with a convenient log to review if anything goes wrong.

Edit your crontab.

]# crontab -e

Find the cronjob from the last tutorial. Make a couple simple edits:

Old Cronjob
23 1 * * 6,4 /usr/bin/geoipupdate

New Cronjob
23 1 * * 6,4 /scripts/custom-scripts/geoipupdate-weekly 2>&1> /usr/share/GeoIP/_last_update.txt

Replace /usr/bin/geoipupdate with the path to your new script.

Send output to a text file, overwriting any existing output:
2>&1>/usr/share/GeoIP/_last_update.txt

That’s it! Now, your WordPress websites will each have the latest MaxMind GeoLite databases.

Using MaxMind Databases with WordPress

Now it’s time to put these databases to work.

Knowledgeable developers can quit reading here. You already know how to create custom WordPress functions and plugins.

Suggested WordPress Plugins

Others have already created plugins that can access MaxMind’s GeoLite databases.

Geolocation IP Detection Plugin

Install and activate as usual. Make sure you carefully review and edit the plugin’s options:

  • Add your MaxMind account and license key.
  • Specify the filepath, eg. wp-content/uploads/GeoLite2-City.mmdb
  • Choose manual download & update if you’re using the cronjob.
  • Automatic update is also available. Do not use the cronjob at the same time. Make sure your WP FTP credentials and folder permissions are correct.
  • Enable Ajax endpoint for cached pages.
  • Review – This server is behind a reverse-proxy. Check the box if you’re using Cloudflare or some other CDN.

Call one of this plugin’s functions to access a visitor’s geolocation information.

function my_user_loc() {
if (function_exists('geoip_detect2_get_info_from_current_ip')) 
	{
	// Get user info object
	$userInfo = geoip_detect2_get_info_from_current_ip();
	// User state, city, country if available
	$userState = $userInfo->mostSpecificSubdivision->isoCode;
	$userCity = $userInfo->city->name;
	$userCountry = $userInfo->country->isoCode;
	}
return array('city' => $userCity, 'state' => $userState, 'country' => $userCountry);
}
// Get User Details
$user = my_user_loc();
// Setup Vars
$city = $user['city']; $state = $user['state']; $country = $user['country'];

Use $city, $state, $country, or any other variable on your WP website, theme, or plugin!

How to Install Maxmind GeoIPUpdate on CentOS with Weekly CronJob

Installing Maxmind’s Geoipupdate on your Centos 7.x server is easy using an .rpm and some basic commands. Here’s the follow-up tutorial explaining how to automate copying MaxMind’s databases to your WordPress /wp-content/uploads folder so they can be used with custom functions or plugins.

Check Your Specs First

Before proceeding, check your server specs and adjust the following instructions appropriately.

Linux OS and Version

]# vi /etc/redhat-release

32 bit or 64 bit system

]# uname -m

32 bit = i686 or i386
64 bit = x86_64

Also make sure your user (root or something else) can execute commands, access the crontab, and can download and install rpms. Typically, root has all the necessary permissions.

Installing Geoipupdate from .rpm

Intended Audience: Novice – Intermediate Linux User

The following describes the process for Centos 7.9.x on a x86_64 machine. Adjust the following for your particular server and Geoipupdate package.

Visit the MaxMind Geoipupdate Github releases page. Find the latest package for your server.

x86_64 servers – Look for linux_amd64.rpm

At time of writing, I used: geoipupdate_4.8.0_linux_amd64.rpm

Login to your server using SSH. Go to the /tmp folder.

If you don’t have one, make one. It’s useful for downloading and unpacking files without disrupting your system.

]# cd /tmp

Suggestion: Remove any older Geoipupdate rpms in your /tmp folder before proceeding!

Next, use wget to fetch the rpm. Once complete, it will be inside your /tmp folder.

]# wget https://github.com/maxmind/geoipupdate/releases/download/v4.8.0/geoipupdate_4.8.0_linux_amd64.rpm

Unpack and install the rpm you just downloaded:

]# rpm -Uvhi geoipupdate_4.8.0_linux_amd64.rpm

A wildcard works assuming you took the suggestion:

]# rpm -Uvhi geoipupdate_4.8.*

Configuring Geoipupdate

The default Geoipupdate configuration file location is /etc/GeoIP.conf. Advanced users can change this location if they want.

Geoipupdate will store fresh database downloads in /usr/share/GeoIP. Again, advanced users can change this location.

Open /etc/GeoIP.conf with an editor like vim or nano.

]# vi /etc/GeoIP.conf

Next, login to your maxmind.com account. Click “Manage License Keys”.

Important: If you haven’t done so already, generate a new license key.
MaxMind will not retrieve an old or lost key. They only display the first few characters of your old key. You’ll have to generate a new one.

Open the following page to see a prefilled GeoIP.conf file with your account number and all available editions for download. Substitute “xxxxxx” with your account number.

https://www.maxmind.com/en/accounts/xxxxxx/license-key/GeoIP.conf

Copy+paste the following into your server GeoIP.conf file:
AccountID  – same as xxxxxx
LicenseKey – Use your existing or newly generated key
EditionIDs – Include all found in the prefilled file.

Suggestion: Only copy+paste the prefilled GeoIP.conf file to your server if you do not want to customize any other settings.

If you overwrite all the optional settings during copy+paste, you won’t be able to edit them later. Best to leave the optional settings intact and commented out for future edits.

Testing Geoipdate Installation

Run Geoipupdate in verbose mode to check for any errors or hiccups. If all goes well, you’ll find each Edition you specified above in #5 in the /usr/share/GeoIP folder.

]# geoipupdate -v
(Make sure that’s a small v, a large V will return the version number).

Configuring Geoipupdate Cronjob

Assuming your test run succeeded, now it’s time to automate Maxmind GeoIP database updates using a CronJob.

First, find the path to geoipupdate. Maxmind’s suggested Cronjob has geoipupdate in /usr/local/bin/.

CentOS 7.x users might find it somewhere else, like /usr/bin. Use “which” to find which one:

]# which  geoipupdate

Open your crontab for editing.

]# crontab -e

Add the following Geoipupdate cronjob, adjusting day and time as you see fit. Make sure you use the path to Geoipupdate from your

]# which geoipupdate output.

23 1 * * 6,4 /usr/bin/geoipupdate

This runs geoipupdate at 1:23 AM on Thursday and Saturday. If manually entering the cronjob is too much, use a Crontab Generator for assistance.

That’s it, you’ll now get the databases twice weekly. Note, MaxMind only updates 1-2x weekly, so a daily download isn’t necessary.

See our companion tutorial for a helpful Bash script that will download MaxMind’s databases using Geoipupdate, then copy each database to your WordPress websites’ /wp-content/uploads folder. This makes them available to custom functions and plugins.

Avoiding Go Get for Now

Note: I’m not a fan of using Go to install Geoipupdate from from Maxmind’s Git source. A failed installation attempt using Go left me with a precarious uninstall process using

]# locate
]# rm

to remove files.

This StackOverflow question has some useful answers. One response suggested

]#  go get package@none

worked in 2021. Unfortunately this didn’t work for me. Another reply recommended this Go answer.