GeoIP with Varnish

Letting varnish handle GEO IP redirects are preferable to letting magento handle the redirects.
This means you no longer need extra magento modules that tend to disable Varnish FPC on first load etc

Compatibility

The default is that varnish will always redirect the customer as per the rules you set up.
However in the following situations the redirect is skipped in order to not break store switches, hurt Google SEO etc.

The visitor will NOT be redirected by Varnish if it:

  • Has visited the domain before

    Determined by the existence of the PHPSESSID and a custom already_redirected cookie

  • Has magento query params ___store= OR ___from_store are present in the URL

    Enables most store switchers to work out of the box.

  • Has the custom magento admin URL path is present in the URL.

    Safety catch so you dont lock yourself out of your admin panel.

  • Its User Agent is a bot. Regexp made from Google etc official docs

    Will match Google Ad,Smartphone,Adsense and most other search engine crawlers.
    Google for example nearly always crawls from the USA and does not like to be redirected.
    Regexp:

    “(?i)(ads|google|bing|msn|yandex|baidu|ro|career|seznam|)bot”

How To

For better reproducible build the varnish GeoIP VCL should be included in your GIT repo.
The same rules will be used for both staging and production sites.

There you will create a VCL that gates what domains to redirect between and what country codes to use.

The backend runs against a continually updated MaxMind GeoIP database and you can find the country codes here:
In your local GIT repo directory create a folder named varnish.
There you add the following snippet as ./geoip.vcl and customize it to match your prod and stage domains.
./varnish/geoip.vcl
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
## If any dev domain matches redirect between them

# Check if any of the prod domains match
if ( req.http.x-host == "my-prod-store.com" ||
     req.http.x-host == "my-prod-store.dk"  ||
     req.http.x-host == "my-prod-store.fi" ) {

    # Redirect to our default store if they are from the USA?
    if ( req.http.x-host != "my-prod-store.com" && req.http.X-Country-Code == "US" ) {
        return ( synth(750, "my-prod-store.com" ));

    # Redirect to our Danish store if they are from the Denmark?
    } elseif ( req.http.x-host != "my-prod-store.dk" && req.http.X-Country-Code == "DK" ) {
        return ( synth(750, "my-prod-store.dk" ));

    # Redirect to our Finnish store if they are from Finland?
    } elseif ( req.http.x-host != "my-prod-store.fi" && req.http.X-Country-Code == "FI" ) {
        return ( synth(750, "my-prod-store.fi" ));
    }
}
# Or Check if any of the stage domains match
elseif ( req.http.x-host == "my-stage-site.com"     ||
         req.http.x-host == "dk.my-stage-site.com" ||
         req.http.x-host == "fi.my-stage-site.com" ) {

     # Redirect to our default store if they are from the USA?
     if ( req.http.x-host != "my-stage-site.com" && req.http.X-Country-Code == "US" ) {
         return ( synth(750, "my-stage-site.com" ));

     # Redirect to our Danish store if they are from the Denmark?
     } elseif ( req.http.x-host != "dk.my-stage-site.com" && req.http.X-Country-Code == "DK" ) {
         return ( synth(750, "dk.my-stage-site.com" ));

     # Redirect to our Finnish store if they are from Finland?
     } elseif ( req.http.x-host != "fi.my-stage-site.com" && req.http.X-Country-Code == "FI" ) {
         return ( synth(750, "fi.my-stage-site.com" ));
     }

 }

You will se your added rules in the build log as well as a confirmation