Comprehensive Guide: Set Up Nginx as a Caching Reverse Proxy on Ubuntu

Apache has built his reputation over a long period and considered to be a most favorite web server. That was due to its proven ability to deal huge traffic and it’s module library that extends its functional as and when needed. But Apache has a weakness and lacks in speed.

On the other hand, Nginx is a comparatively new entrant in the market or more precisely, Nginx is not that aged as Apache but it has established itself for speed, reliability, less resource hungry and its ability to deal Reddit traffic effect. We have stats of 2016 showing the market share of the web server. Just observe the market share of Nginx as compared to giants like IIS, Apache etc.

If you need Apache for your project due to some reasons and want to speed up your WordPress site, you should deploy Nginx as a reverse proxy and cache solution to provide your users with blazing fast content.

Nginx as a reverse proxy works very well with Apache. Nginx listens on port 80 while Apache reserves 8080 for its functionality. Nginx deals at the front end and receives requests from visitors. If desired request or page is cached by Nginx, it will serve the request with cached pages without referring to Apache. while all other requests are routed to Apache for processing of PHP With MySQL or MariaDB.

What exactly a Reverse Proxy is?

In simple words reverse proxy acts as a communication bridge between the client and actual web server. A client makes the request, reverse proxy takes it and forward it to one or more web server for proper distribution of load and final execution. The web server(s) process and returns back the result to the to the proxy server for further delivery of the response to the client.

Benefits of Nginx Reverse Server Proxy

Setting up Nginx as reverse proxy server gives great benefits. Important factors are;

  • Increased Security
    Nginx as a proxy server is your first line of defense against all security threats. Most importantly it totally hides out the footprint of your back end web server.
  • Load Balancing
    A proxy server could also be configured to act as a load balancer. Nginx, in this case, distributes the load as per configuration and priorities set in the conf file. It also allows configuring your fallback server in case some server is failed to cope up with the load. For example, if you have a server with low in resources in your upstream fleet and you can configure after how many failed attempts, traffic will be diverted to remaining server. Isn’t interesting?
  • Better Performace
    Nginx is well known for delivery of static content with blazing fast speed. SO all of your static content is served by Nginx with great speed. You can even configure the location of cache on system ram to make it lightning bolt.

How to setup Nginx as Reverse Proxy Server

Now up to this point, we have a good understanding of reverse proxy server and specially Nginx performance. Let’s start with the installation of Nginx and configuration of the whole setup. Assuming that you already have LAMP stack installed on Ubuntu, we will install and configure Nginx as reverse proxy and cache solution for your WordPress.

Let’s start with Apache configuration to listen on port 8080 leaving default 80 port for Nginx. Open Apache port file to change the for listening to 8080,

sudo nano /etc/apache2/ports.conf

change the port 80 to 8080

Listen 8080

Open the Apache virtual host file to change the port here too. You must have your site specific vhost file for Apache. We will use wordpress.conf for demonstration purpose.

sudo nano /etc/apache2/sites-available/wordpress.conf

Change the port to 8080 in the virtual host

<VirtualHost 8080>

You are required to change all of your Apache virtual hosts to listen on port 8080.

To make new configuration effective, it’s compulsory to restart the Apache service but we will do this at a later stage to minimise down time.

Installation of Nginx

Install Nginx and Nginx-extras to get the ngx_cache_purge module, which will make it easier to manage the Nginx proxy cache.

sudo apt-get install nginx nginx-extras -y

Nginx already has a predefined configuration file available at /etc/ngnix/sites-available. You can modify it or create a sperate for your project.

sudo nano /etc/nginx/sites-available/default

Now configure Nginx vhost file,

#fix 504 gateway timeouts, can go in nginx.conf
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

#set the location of the cached files, zone, name, size (100 MB) and how long to cache for 600 minutes
proxy_cache_path /var/run/proxy-cache levels=1:2 keys_zone=WORDPRESS:10m max_size=100m
inactive=600m;
proxy_cache_key $scheme$host$request_uri;

#prevent header too large errors
proxy_buffers 256 16k;
proxy_buffer_size 32k;

#httpoxy exploit protection
proxy_set_header Proxy "";

server {
listen 80 default;
access_log /var/log/nginx/proxy-access.log;
error_log /var/log/nginx/proxy-error.log;
add_header X-Cache $upstream_cache_status;

set $do_not_cache 0;
set $bypass 0;

#security for bypass
if ($remote_addr ~ "^(127.0.0.1|Web.Server.IP)$") {
set $bypass $http_secret_header;
}

if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
set $do_not_cache 1;
}

location / {
proxy_set_header Host $host;
proxy_redirect off;
proxy_cache WORDPRESS;
proxy_cache_revalidate on;
proxy_ignore_headers Expires Cache-Control;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_bypass $bypass $do_not_cache;
proxy_no_cache $do_not_cache;
proxy_cache_valid 200 301 302 500m;
proxy_cache_valid 404 1m;

#can rename PURGE to whatever you want, should restrict it to back-end server requests for security
proxy_cache_purge PURGE from 127.0.0.1 Web.Server.IP;
proxy_pass http://127.0.0.1:8080;
}

location ~ /purge(/.*) {
allow 127.0.0.1;
allow Web.Server.IP;
deny all;
proxy_cache_purge WORDPRESS $scheme$host$1;
}
}

Save changes by Pressing Ctrl + X, Y and Enter

Create symbolic Nginx vhost links for sites-enabled. It’s equivalent to a2ensite site-name Apache command for activation for the desired vhost.

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

Test your Nginx configuration for any mistakes. Issue following command. Restart Nginx to make your vhost effective.

nginx -t

if your configuration has no mistake, Nginx test will return ok message. It’s the time to restart Nginx and Apache to make your whole configuration effective.

sudo service nginx restart
sudo service apache2 restart

Now with this command, your Nginx is listening on port 80 while Apache on 8080.

Testing the Nginx reverse proxy cache
We will use curl to check that the caching feature is working on our WordPress site.

sudo apt-get install curl -y

Now curl is installed and we can start testing Nginx Reverse proxy. Use SSH on the web server to run the curl command. This will verify that your home page is cached by a reverse proxy server, and the -I flag ensures that we get the response headers back from the reverse proxy server

curl -I http://smashinglab.com/

The key here is the status of X-Cache

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Cache: HIT

If the home page is not cached, you will receive the following response X-Cache

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Cache: MISS

You may need to curl twice to get your content cached and get HIT response.

This can also be confirmed from /var/run/proxy_cache, as Nginx will store all cached content in proxy_cache as defined by us in vhost configuration file.

Clearing and invalidating the reverse proxy cache in Nginx
Thanks to the ngx_cache_purge module, which is included in the Nginx-extras package, we have several ways to flush the cache to server updated version of our content from the cache.

Our goal is to have the entire site cached using this plugin so your WordPress site is fully cached and always fast. When we update the content we want to clear the cache for that particular posts, pages or categories that will replace that old content with fresh new ones at once, so that your users always get the fastest possible experience.

The Nginx proxy cache is stored in the folder structure in the /var/run/proxy-cache location, in which we can selectively delete certain items or delete everything to clear the entire cache.

BYPASS allows you to forcefully update posts or pages by specifying a web server where WordPress is offered for the new version. The updated version replaces the old content in the Nginx reverse proxy cache.

The PURGE method, proxy_cache_purge, allows you to clear specific items from the cache.

Clear the entire cache in the reverse Nginx proxy server

If you want to clear the entire cache, you can simply delete the contents of the proxy cache folder manually

rm -R /var/run/proxy-cache/*

If you want to clear the entire cache with regular expressions (also known as wildcards), your only option is to use Nginx Plus, which is worth the money. Nginx Plus engineers know that having a high-performance WordPress site means saving the entire site in a cache all the time so large companies will pay for flexible cache management.

Update products in the reverse Nginx proxy using BYPASS

Bypass is definitely the best way to update the Nginx cache of a reverse proxy server. With proxy_cache_bypass, you forcibly update the cached version of the URL of a web server running WordPress. Your users will never get old content this way

In the block above we implemented proxy_cache_bypass only for queries that come from our web server or the reverse proxy server itself

We allowed a secret header for incoming requests from the web server and a reverse proxy server, so we can check using the secret header with Curl Of these servers.

curl -I http://smashinglab.com -H "secret-header: true"

You will see this output, showing BYPASS in X-Cache header

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Cache: BYPASS

If you try the same curl command from another server, you will just see the HIT response

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Cache: HIT

Updating cached content using the PURGE method
The PURGE method is provided by the ngx_cache_purge module in the Nginx-extras package. For this method to work, we have proxy_cache_key, which should have been set to $scheme$host$request_uri.

To send a request to PURGE, using this syntax, the proxy_cache_purge module will translate the query into the md5 hash URL and remove the item from the proxy_cache_path.

curl -X PURGE -I https://smashinglab.com/

If the reverse proxy server has a file, then you get a response of 200, which means successful

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Connection: keep-alive

If Nginx reverse proxy does not have such a cached specific URL then you will get 404

HTTP/1.1 404 Not Found
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive

If Nginx reverse proxy server detects that on your IP addresses You are not allowed to execute PURGE requests, you will get the response: 403 Forbidden

HTTP/1.1 403 Forbidden
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive

This type of Nginx reverse proxy security is important because it limits PURGE requests to a whitelist of your trusted servers

Purge elements in the Nginx Reverse proxy using the / purge URL method

The purge URL method uses a specific URL to call the Nginx proxy_cache_purge method, which we implemented above.

To clean up using the URL, use the curl command to clear the home page, the slash is represented

curl https://smashinglab.com/ -I

You will see this response if the home page is cached in the reverse proxy server of Nginx and you successfully clean it

HTTP/1.1 200 OK
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive

If your reverse Nginx proxy does not have a cached home page in WordPress, you will receive an error message 404. And if your reverse Nginx proxy does not allow you to access the purge location, you will get an error: 403 Forbidden

HTTP/1.1 403 Forbidden
Server: nginx
Date: Sat, 25 Aug 2017 08:53:14 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive

Similar to the PURGE method, we restrict access to the place/purge using the white-list IP Addresses, So that attackers can not overload your web server running WordPress.

If You Like Our Work on Smashing Lab, You Should Consider:

  1. Stay Connected to: Twitter | Facebook | Google Plus
  2. Subscribe to our email updates: Sign Up Now
  3. Get your own Virtual Private Server at ($5.00/month).

We are thankful for your never ending support.

Imran Yousaf

I am Imran Yousaf, a computer geek, founder of the site Smashinglab.com. I am a die hard fond of open-source software and Linux operating system. In addition to Linux, I am interested in everything related to information technology and modern science.

Your name can also be listed here. Got a tip? Submit it here to become a Smashing Lab author.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *