Wordpress with Cloudflare on NGINX - an 'Easy' way

wordpress
nginx

#1

So, Wordpress seems pretty popular around here - and NGINX is pretty awesome for large sites (and small ones too!) - so let’s see about setting them up without spending hours debugging NGINX configs and server blocks!

Disclaimer: I am not affiliated with any projects, services or plugins mentioned. This guide assumes you have just spun up a fresh server and have sudo user or root access via SSH - as there are a few commands you must perform from the command-line. Über-power-users that want to config NGINX themselves need not apply, though they may certainly hack away at their own risk once it is installed.

This will walk you through installing NGINX and the latest Wordpress using EasyEngine, which automates installation of the LEMP stack and Wordpress. EasyEngine supports Ubuntu 12.04, 14.04 and 16.04 & Debian 7 and 8. Note that this is a standalone installation of NGINX - as opposed to a reverse-proxy in front of Apache, which is also popular out there.

This guide is intended for someone who wants to try out Wordpress on NGINX, but doesn’t want to waste time setting everything up! Manual setup can definitely be rewarding (and usually preferable) but sometimes you want to go for a test-drive without assembling the car first.

There are many comparisons out there between Apache and NGINX and I won’t attempt to list pros/cons here - so do some research first and then proceed if you like!

For this demo I spun up a 1vCPU/512MB Vultr VC2 instance running Ubuntu 16.04.

Pre-installation

Before proceeding with EasyEngine & Wordpress installation it is recommended to perform the following tasks if necessary on your server

  • Add a user and give them sudo privileges
  • Configure ssh keys and disable password authentication & root login in your ssh config
  • Configure firewall (ufw) & enable for OpenSSH, HTTP and HTTPS (and optional: TCP 22222)

Cloudflare - Part I

Linking your site with Cloudflare is a two step process, done before and after Wordpress installation.

  1. Ensure your domain is set to point to your registrar’s nameservers. This is usually the case by default for new domains.

  2. Go to Cloudflare’s website and sign up for a free account (if you don’t already have one) and follow the steps to add a website. When prompted to confirm your DNS settings, ensure that the A record for example.xyz is set to your server’s IP address. Proceed with setup and make note of the Cloudflare nameservers that are provided to you ([name].ns.cloudflare.com) - the remainder of the settings on the Cloudflare dashboard will be set later via the Cloudflare Wordpress plugin (except for one thing that we’re going to disable later on).

  3. While still on the Cloudflare dashboard, select Overview and scroll down to Domain Summary to find the ‘Get your API key’ link. Scroll down the next page to ‘Global API key’ and click the button to get your API key. You will need this later.

  4. Log into your domain registrar’s dashboard and change the nameservers to the ones provided during Cloudflare site setup (step 2).

  5. Wait a little while (varies), and then perform the following in your terminal (do not include the ‘$’ - that is just there to indicate this is a terminal command):

    $ dig example.xyz ns +short

    The nameservers you entered in step 4 should be displayed. If not, wait a while and dig some more until the correct nameservers appear in the output - then proceed. Note that ‘a while’ could be 24-48 hours depending on your location and DNS propagation.

  6. Back on the Cloudflare dashboard (website) > Overview tab, you should see that your site is ‘grey’ and there is a ‘Recheck Nameservers’ button. You can only click this every hour I believe, so before you do ensure the previous step has been completed successfully, then click the button. Your site should ‘turn green’ in the Cloudflare dashboard.

EasyEngine Installation

Connect to your server via SSH and perform the following

  1. $ sudo apt update && sudo apt upgrade -y

  2. $ mkdir ~/easyengine && cd ~/easyengine

  3. $ wget -qO ee rt.cx/ee && sudo bash ee

You will be prompted to enter a name and email address

  • Name is used as admin user name
  • Email address is used to receive automated emails from EasyEngine installation script regarding new installations

You can now use the ee command to perform Wordpress installations.

Creating a Wordpress site

The following command was used to create the Wordpress site for this demo:

$ sudo ee site create example.xyz --php7 --wpfc

This creates a Wordpress site using:

  • PHP7
  • NGINX fastcgi_cache (this option also installs the w3 total cache plugin for Wordpress)

Notes:

  • Replace example.xyz with your FQDN, leaving out the ‘www’
  • You may omit --php7 to install the default PHP5.6.

Other caching options at installation:

  • ee site create example.xyz --wp install wordpress without any page caching
  • ee site create example.xyz --w3tc install wordpress with w3-total-cache plugin
  • ee site create example.xyz --wpsc install wordpress with whisp-super-cache plugin
  • ee site create example.xyz --wpredis install wordpress + nginx redis_cache

You will be prompted to confirm installation of PHP7 if you choose that option. Installation will progress (sometimes slowly) and admin credentials will be displayed in your terminal upon completion - copy these down somewhere now.

Wordpress Configuration

Plugin Installation

  1. Navigate to example.xyz in your browser and confirm installation.

  2. Navigate to example.xyz/wp-admin and log in. Once at the Wordpress dashboard navigate to Plugins > Add New, and install and activate the following plugins:

Autoptimize

Navigate to WP dashboard Settings > Autoptimize and peform the following:

  1. Click ‘Show advanced settings’
    • You may want to experiment with these later, though it’s not required
  2. Enable ‘Optimize HTML code’
  3. Enable ‘Optimize JavaSCript code’
  4. Enable ‘Optimize CSS code’
  5. Click ‘Save Changes and Empty Cache’

W3 Total Cache

  1. Navigate to WP dashboard > Performance > General Settings and set or verify the following:

    • Page Cache: Enable > set to ‘Disk: Enhanced’
    • Minify: leave disabled
    • Opcode cache: set to ‘Opcode: Zend Opcode’
    • Browser cache: Enable
    • Click ‘Save settings and purge caches’
  2. Navigate to WP dashboard > Performance > Page Cache and set or verify the following:

    • Automatically prime the page cache: Enable and leave default settings
    • Click ‘Save settings and purge caches’
  3. Navigate to WP dashboard > Performance > Browser Cache and set or verify the following:

    • Set expires header: Enable
    • Set cache control header: Enable
    • Set entity tag (ETag): Enable
    • Set W3 Total Cache header: optional
    • Enable HTTP (gzip) compression: Enable
    • Click ‘Save settings and purge cache’
    • All of these changes will be propagated down to the various filetype categories further down the page, which you may modify on a more granular level if you wish
  • If you would like to learn more about W3TC and the various settings available, this article is pretty in-depth.
  • Note that I do not enable the Cloudflare extension in W3TC because it is very limited on features and the ones that it does have are already present in the official Cloudflare plugin.

Purge Caches

Navigate to WP dashboard > Top Menu Bar. From left-to-right:

  1. Highlight Autoptimize > click Delete cache
  2. Click Purge Cache
  3. Highlight Performance > click Purge All Caches
  • Important: You should do this whenever you activate/deactivate plugins or otherwise make major changes in wp-admin

Cloudflare - Part II

  1. Navigate to WP dashboard > Settings > Cloudflare

    • Click the ‘sign in here’ link
    • Enter your email and API key from earlier
    • The Home tab will be displayed. Click Apply next to ‘Optimize Cloudflare for Wordpress’
    • Click ‘Purge Cache’ > ‘Purge Everything’
    • Optional: enable ‘Automatic Cache Management’
  2. On the Cloudflare dashboard (website) navigate to the Speed tab and disable Auto Minify for all three filetypes.

    This setting is enabled when clicking ‘Optimize’ in the previous step, however the Autoptimize Wordpress plugin is already minifying your files - having both minification methods enabled can result in unintended consequences. I prefer to do minification server-side via Wordpress plugin instead of having Cloudflare do it, but you are free to test both options if you are trying to minimize Wordpress plugins.

Switch to HTTPS (recommended)

  1. Navigate to WP dashboard > Settings > General

    • Change the WordPress Address (URL) to https://example.xyz
    • Change the Site Address (URL) to https://example.xyz
    • Click ‘Save Changes’
      • You may be automatically logged out of wp-admin at this point
  2. On the Cloudflare dashboard (website):

    • Navigate to the Crypto tab, scroll down, and enable ‘Always use HTTPS’
    • Navigate to Page Rules tab and add the following page rule https://*example.xyz/wp-admin/*
      • With the setting - Cache Level: Bypass
  3. Log back in to example.xyz/wp-admin and notice that you are now using SSL connection

Caveats

  • Despite writing this guide, I do not run Wordpress for any of my production sites at this time, though I do stick with NGINX as a webserver. When I was using Wordpress I used EasyEngine because it was very simple to spin up a Wordpress site with just a single command. There may very well be Ansible playbooks or Puppet configs out there that install LEMP & Wordpress, which are better with more current version of PHP, etc. that I just don’t know about. Who knows I may even write one!

  • EasyEngine will be moving to V4 at some point and support for the current version seems to have slowed. V4 sounds like a major overhaul and the blog has not been updated since April.

  • Accessing the EasyEngine ‘admin’ page on port 22222 can only be done via your origin IP, e.g. 192.168.0.77:22222, not example.xyz:22222 (also the ‘admin’ site is extremely limited. I recommend sticking to the command-line for admin functions).

  • PHP7.0 is installed though the current stable version is 7.1.X.

  • YMMV regarding performance improvements.


Using wordpress caching plugin with cloudflare
#2

nice, but FYI nginx security vulnerability release was just made for 1.12.1 and 1.13.3 https://forum.nginx.org/read.php?2,275424

Hello!

A security issue was identified in nginx range filter. A specially
crafted request might result in an integer overflow and incorrect
processing of ranges, potentially resulting in sensitive information
leak (CVE-2017-7529).

When using nginx with standard modules this allows an attacker to
obtain a cache file header if a response was returned from cache.
In some configurations a cache file header may contain IP address
of the backend server or other sensitive information.

Besides, with 3rd party modules it is potentially possible that
the issue may lead to a denial of service or a disclosure of
a worker process memory. No such modules are currently known though.

The issue affects nginx 0.5.6 - 1.13.2.
The issue is fixed in nginx 1.13.3, 1.12.1.

For older versions, the following configuration can be used
as a temporary workaround:

max_ranges 1;

Patch for the issue can be found here:

http://nginx.org/download/patch.2017.ranges.txt

easyengine’s nginx version is severely outdated now as they custom build their own nginx version and it hasn’t been updated in ages. So check with EE folks about an nginx update ASAP

also check for PHP 7 too as 7.0.21 and 7.1.7 security releases were released too

edit: might not matter that much if you have cloudflare nginx proxy in front though I suppose :slight_smile:


#3

Hey yes thank you for posting about the vulnerability. I’m aware that easyengine is not keeping up, which is mentioned at the bottom of my somewhat lengthy post. I do not foresee any updates to easyengine until they release V4, which may put people off from trying it out - that’s up to them of course.

I also just realized that you’ve got a LEMP stack available for CentOS which I’m definitely going to check out!


#4

Yeah, though it really should take any time at all to spit out a new nginx build for EE if they wanted - they already have the build process scripted and automated AFAIK.

yup, Centmin Mod 123.09beta01 is the one to look at