Install WordPress on NGINX with FastCGI Cache in Ubuntu

WordPress on NGINX with FastCGI Cache

If you are running a WordPress blog or website on NGINX Webserver, then you should also enable FastCGI caching module, because FastCGI is not only better but also faster when we compare it with WP Super Cache and W3 Total Cache under heavy load. We can simply say it eliminates the need of caching plugin inside WordPress. In this tutorial, we are going to set up NGINX with FastCGI Cache module, and we are using MariaDB instead of MySQL for bit better performance. We are going to use the following things…

  • Ubuntu 14.04 LTS (12.04 LTS)
  • NGINX Custom (Thanks to rtCamp to Maintain a Stable PPA)
  • MariaDB (5-10% Better than MySQL)
  • PHP-FPM (Lightweight PHP)
  • Postfix (Basic: For contact forms to work)

Let’s set up a VPS or Dedicated machine which is running on Ubuntu LTS, I will suggest LTS only because they have long term support and stable enough to secure your machine. I personally like DigitalOcean, the best and leading cloud hosting company based on Fast SSD hard drive which makes things process super fast.

Install NGINX with FastCGI Purge Module

NGINX’s default installation does not have FastCGI Cache Purge mechanism, so we need to compile Nginx-Cache-Purge module with it. But it is something which requires geeky knowledge. Since rtCamp made this simple by maintaining PPA repository we can use that.

sudo apt-get update
sudo apt-get install python-software-properties -y
sudo add-apt-repository ppa:rtcamp/nginx
sudo apt-get update
sudo apt-get install nginx-custom

This installation will install NGINX with FastCGI Purge module; which will enable us to use WordPress on FastCGI Cache and cache purge ability will be better because the FastCGI Purge module is installed. To confirm whether your setup has FastCGI Purge module or not use below command and check its output.

nginx -V 2>&1 | grep nginx-cache-purge -o

If you see nginx-cache-purge in output that means we have a purge module.

Install PHP-FPM

sudo apt-get install php5-fpm php5-mysql

Now we need to secure the PHP by default it has a small loop for hackers (don’t be panic) for which we need to edit PHP.ini file. We can use any text editors like nano or vim. In our case, we are using my favorite editor nano.

sudo nano /etc/php5/fpm/php.ini

Now find “cgi.fix_pathinfo” without quotation mark. Use Ctrl+W to activate search function in nano editor. Now you will see that its value is set to 1 by default like this cgi.fix_pathinfo=1, so change its value to 0 like this: cgi.fix_pathinfo=0 and save it via Ctrl+O.

Install MariaDB

sudo apt-get install mariadb-client mariadb-server
sudo service mysql start

Now we have installed MariaDB client as well as server; let’s configure it for production or what we say is a secure environment.


While installation you have to provide some security answers just follow below answers.

In order to log into MariaDB to secure it, we’ll need the current
password for the root user. If you’ve just installed MariaDB, and
you haven’t set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on…

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] N
… Success!

You can change your default password here; if you want to. In this tutorial we didn’t change the password since we have given strong one back while installing MariaDB.

Remove anonymous users? [Y/n] Y
… Success!

Normally, root should only be allowed to connect from ‘localhost’. This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
… Success!

By default, MariaDB comes with a database named ‘test’ that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
– Dropping test database…
ERROR 1008 (HY000) at line 1: Can’t drop database ‘test’; database doesn’t exist
… Failed! Not critical, keep moving…
– Removing privileges on test database…
… Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
… Success!

Cleaning up…

All done! If you’ve completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

TIP: While setup you will be asked for passwords use one strong nuclear one.

Install PhpMyAdmin

Managing databases without a user interface might be painful. Thus we are using PhpMyAdmin which will be easily accessible.

sudo apt-get install phpmyadmin
sudo ln -s /usr/share/phpmyadmin/ /var/www/html/
sudo service nginx restart

Because we had made a symbolic link of PHPMyAdmin to /var/www/html location which is default path or root directory of our site the PhpMyAdmin will be accessible from http://IP-or-Domain/phpmyadmin location.

Install Postfix

sudo apt-get install postfix

Without Postfix our server won’t able to send emails from forget password and contact us forms. Also, we do not have to configure anything here just hit enter or okay. Let all the value set to default.

Finally Configure NGINX’s Server Blocks and Install WordPress

Before we move ahead to install WordPress let’s configure the NGINX’s default server blocks. In NGINX there is no support of .htaccess files so all we need to configure NGINX’s server blocks.

Simply edit the following file,

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

Now delete all default lines.

Do not worry we have all these default lines in the arranged pattern.

TIP: Use Ctrl+K to cut all lines instead of delete. There is no direct way to delete all.

Now paste below whole code on a clean editor screen.

fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
server {
listen 80 default_server;
root /var/www/html;
index index.php index.html index.htm;
charset UTF-8;
set $skip_cache 0;
if ($request_method = POST) {
set $skip_cache 1;
if ($query_string != "") {
set $skip_cache 1;
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|/wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
location / {
try_files $uri/ /index.php?$args;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 60m;
location ~ /purge(/.*) {
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
location ~* \.(js|css|png|jpg|jpeg|gif|ico|eot|otf|ttf|woff)$ {
add_header Access-Control-Allow-Origin *;
access_log off; log_not_found off; expires 30d;
location = /robots.txt { access_log off; log_not_found off; }
location ~ /\. { deny all; access_log off; log_not_found off; }

Just replace your domain names from server_name line (9).

Save the file and restart services.

sudo service nginx restart
sudo service php5-fpm restart

Now the WordPress Download… and further configs.

cd /var/www/html
sudo apt-get install zip
sudo apt-get install unzip
sudo unzip
cd wordpress
sudo mv * /var/www/html
sudo rm -rf wordpress
sudo chown -R www-data:www-data /var/www/
cd ..

Now we have WordPress files ready and now need to connect it with a Database.

  1. Open PhpMyAdmin in a browser and create a database over there. Enter in that database and move to Privileges Tab and click on Add User.
  2. In login information give a username to the database, set host to localhost and give a password. (Better you use a Password Generator option there)
  3. Not down Database name, Username, and Password. (We need to add them in the wp-config.php file)
  4. Under Database for user section Check/Tick on Grant all privileges on database “DATABASE_NAME”.
  5. Now click on Go. (Do not check/tick anything under Global privileges section)

Now we have a database ready. Let’s connect WordPress to Database.

sudo mv wp-config-sample.php wp-config.php
sudo nano wp-config.php

Edit database name, username, and password; once done save the file.

Yahhh!!! we done everything just open a browser and open your site with IP address or domain name and do first time WordPress setup and continue using the WordPress.

Now install NGINX Helper (by rtCamp) plugin in WordPress and use it for purging the cache files. Also to minimize the load of database DB Cache Reloaded Fix plugin with default settings. Trust me it is far better than WP Super Cache and W3 Total Cache.

Leave a Reply

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


  1. Murali Avatar

    Hi, Need to update this to prevent font awesome not showing in browser.

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|eot|otf|ttf|woff)$ {
    add_header Access-Control-Allow-Origin *;
    access_log off; log_not_found off; expires 30d;
    1. AtulHost Avatar

      Hello Murali,

      In our setup we never faced any issue of Font Awesome is not loading properly. However thanks for your contribution; I really appreciate it. Since we are doing setup on dedicated server or vps you are free to add any file extension type using “|” symbol without quotes. As we are using FastCGI Cache do not forget to flush cache and use plugin Query Strings Remover for hassle free caching (since default WordPress themes and static files have many query strings).

  2. Murali Avatar

    Hi Atul,
    Oh my setup using local server with Lubuntu LTS 14.04 which occur this problem if I insert the code all browser fine otherwise all icon is missing.

    1. AtulHost Avatar

      Thanks Murali for letting me know the case, As this tutorial is based on Ubuntu, there might be any chance of directory permission issue. I better suggest to inspect element and check network tab and refresh browser once to verify why font-awesome is not loading. However I appreciate you yourself managed to make it work fine. Thanks for sharing the code. If anyone found any issue with font-awesome then he/she will sure follow your contributed code.

  3. Thomas Avatar

    Thanks a ton very nice write up, I just started using nginx and now having FastCGI Cache super awesome!!! You’re a lifesaver.

  4. Waqas Avatar

    How does location ~ /purge(/.*) { } works?

    Should we hit url in browser like

    1. AtulHost Avatar

      This purge technique functions like a curl action. When a directory is pinged with purge scheme it purges the cache. I highly recommend to start any new project with updated one only follow this new one – Install WordPress with NGINX PHP7 PHPMyAdmin on Ubuntu, it supports everything and consumes less hardware.

  5. Ravi Avatar

    I am current using VestaCP. This panel has everything under templates. Just scared to screw up with them. Will try to do a test installation of vesta and tinker these conf into it.

    On a side note, Which You think is better Caching WP on NGINX with Redis or PHP FastCGI? Less load on server better performance benefit with future scalability?

    1. AtulHost Avatar

      Hi, Ravi, I am glad to know that one geek is trying to do some research. First of all, I never used VestaCP, as I am using the direct method to host websites as mentioned in this post. I have done some good amount of research on this particular field and found that when we talk about NGINX, forget about much of automation. I will suggest going with EasyEngine as they are awesome guys who made NGINX easy to use for beginners.

      About side note:

      I use NGINX as Web Server, PHP7 for PHP, FastCGI as Frontend Full Page Caching and also use Redis as Database and Object Cache.

      If you have a simple or somewhat less database querying site then consider NGINX with PHP7 and use FastCGI cache it is enough to handle to much traffic.

      If you have a bigger site with the busy database then use Redis as Database and Object cache but make a note of that using Redis on fresh site which has no load is useless.