38
WordPress-NGINX Best Practices (With EasyEngine) by Rahul Bansal (rtCamp)

WordPress + NGINX Best Practices with EasyEngine

Embed Size (px)

Citation preview

Page 1: WordPress + NGINX Best Practices with EasyEngine

WordPress-NGINX Best Practices

(With EasyEngine)

by Rahul Bansal (rtCamp)

Page 2: WordPress + NGINX Best Practices with EasyEngine

WordPress-NGINX - Best practices

Page 3: WordPress + NGINX Best Practices with EasyEngine

“If you can do it in NGINX, just do it in

NGINX!”

The Rule!

Page 4: WordPress + NGINX Best Practices with EasyEngine

#1. nginx fastcgi-cache

Page 5: WordPress + NGINX Best Practices with EasyEngine

Purpose

● Best solution for serving content to non-

logged in users

● Should be used instead full-page-cache from

WordPress plugin

Page 6: WordPress + NGINX Best Practices with EasyEngine

Global Code Fragment

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 updating timeout

invalid_header http_500;

Page 7: WordPress + NGINX Best Practices with EasyEngine

server {

location ~ \.php$ {

try_files $uri =404;

include fastcgi_params;

fastcgi_pass 127.0.0.1:9000;

fastcgi_cache WORDPRESS;

fastcgi_cache_valid 60m;

fastcgi_cache_bypass $skip_cache;

fastcgi_no_cache $skip_cache;}}

Site config

Page 8: WordPress + NGINX Best Practices with EasyEngine

Cache conditions

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|index.php") {

set $skip_cache 1; }

if ($http_cookie ~* "comment_author|wordpress_[a-f0-

9]+|wordpress_logged_in") {

set $skip_cache 1; }

Page 9: WordPress + NGINX Best Practices with EasyEngine

Cache conditions

if ($request_uri ~* "/store/|/random/|/wp-admin/|...") {

set $skip_cache 1; }

if ($http_cookie ~* "comment_author||yummy_cookie|...") {

set $skip_cache 1; }

if ($remote_addr ~* "1.2.3.4") {

set $skip_cache 1; }

Page 10: WordPress + NGINX Best Practices with EasyEngine

if ($query_string != "") {

set $skip_cache 1; }

# for http://example.com/?s=hello

if ($arg_s != "") {

set $skip_cache 0; }

Caching search result pages

Page 11: WordPress + NGINX Best Practices with EasyEngine

Caching multiple versions of a page

# Cookie Example

fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_country";

# User-Agent Example

set $mobile no;

if ($http_user_agent ~* "iphone|android|blackberry|netfront") {

set $mobile yes;}

fastcgi_cache_key "$scheme$request_method$host$request_uri$mobile";

Page 12: WordPress + NGINX Best Practices with EasyEngine

#2. NGINX substitution module

CDN & SSL Warning fix

Page 13: WordPress + NGINX Best Practices with EasyEngine

Original URL => example.com/wp-content/uploads/hello.jpg

CDN URL => cdn.example.com/wp-

content/uploads/hello.jpg

sub_filter "example.com/wp-content/uploads/"

"cdn.example.com/wp-content/uploads/";

sub_filter_last_modified on;

sub_filter_once off;

CDN (Origin Pull)

Page 14: WordPress + NGINX Best Practices with EasyEngine

sub_filter "http://example.com/wp-content/"

"https://example.com/wp-content/";

sub_filter_last_modified on;

sub_filter_once off;

SSL - mixed content warning fix

Page 15: WordPress + NGINX Best Practices with EasyEngine

#3. pagespeed module

Reduce load time

Page 16: WordPress + NGINX Best Practices with EasyEngine

● css/js minify & combine.

● search-replace URL for CDN

● on the fly image (lossless) compression

● lazy loading for images

pagespeed module

Page 17: WordPress + NGINX Best Practices with EasyEngine

# CSS

pagespeed EnableFilters combine_css,rewrite_css;

# JS

pagespeed EnableFilters combine_javascript,rewrite_javascript;

# Images

pagespeed EnableFilters lazyload_images;

pagespeed EnableFilters rewrite_images;

pagespeed EnableFilters convert_jpeg_to_progressive

site specific filters

Page 18: WordPress + NGINX Best Practices with EasyEngine

# Turning the module on and off

pagespeed on;

# Configuring PageSpeed Filters

pagespeed RewriteLevel PassThrough;

# Needs to exist and be writable by nginx. Use tmpfs for best performance.

pagespeed FileCachePath /var/ngx_pagespeed_cache;

pagespeed global config

Page 19: WordPress + NGINX Best Practices with EasyEngine

#4. Upstream Module

Load Balancer/Failover

Page 20: WordPress + NGINX Best Practices with EasyEngine

upstream backend {

ip_hash;

server 1.1.1.1;

server 2.2.2.2;

server 2.2.2.2;

}

load balance mode

Page 21: WordPress + NGINX Best Practices with EasyEngine

failover mode

upstream backend {

server 1.1.1.1 max_fails=3 fail_timeout=30s;

server 2.2.2.2 backup;

}

Page 22: WordPress + NGINX Best Practices with EasyEngine

Front-end site config

location / {

proxy_pass http://backend;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

#proxy_cache

}

Page 23: WordPress + NGINX Best Practices with EasyEngine

Backend NGINX Config

#gloabal config

set_real_ip_from 9.9.9.9;

real_ip_header X-Forwarded-For;

Page 24: WordPress + NGINX Best Practices with EasyEngine

What if load balancer fails?

● Configure backend server with NGINX in a

way that it can run as standalone server

● Use DNS-based failover to switch traffic from

load balancer to a backend server

Page 25: WordPress + NGINX Best Practices with EasyEngine

#5. Upstream mod with HHVM

Speed for logged in users

Page 26: WordPress + NGINX Best Practices with EasyEngine

HHVM with PHP-FPM fallback

upstream php {

server 127.0.0.1:8000; #hhvm

server 127.0.0.1:9000 backup; #php-fpm

}

Page 27: WordPress + NGINX Best Practices with EasyEngine

More Tricks

The list is endless!

Page 28: WordPress + NGINX Best Practices with EasyEngine

#enable SSL cache

ssl_session_cache shared:SSL:20m;

ssl_session_timeout 10m;

#enable spdy

server {

listen 443 ssl spdy;

}

SSL and spdy

Page 29: WordPress + NGINX Best Practices with EasyEngine

URL Redirection#For Single URL

location = /old/path {

return 301 http://foo.com/new/url;

}

#For Complete Section

location ~ /old/(.*) {

return 301 http://foo.com/new/$1;

}

Page 30: WordPress + NGINX Best Practices with EasyEngine

Security with Limit Request Module

#global

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

#server

location = /wp-login.php {

limit_req zone=one burst=1 nodelay;

include fastcgi_params;

fastcgi_pass 127.0.0.1:9000;

}

Page 31: WordPress + NGINX Best Practices with EasyEngine

Memcache/Redis - Distributed Cache

● For wordpress site is spread across multiple servers

● Only extra work is, WordPress/PHP side codes are

needed to “fill” cache

● For Memcache, NGINX has a core and few third party

modules

● For redis, NGINX has third party modules

Page 32: WordPress + NGINX Best Practices with EasyEngine

Using EasyEngine

Page 33: WordPress + NGINX Best Practices with EasyEngine

● A script to setup and manage multiple

wordpress sites with NGINX web server

● Always up to date with best practices,

including most of the stuff we discussed so

far

What is EasyEngine?

Page 34: WordPress + NGINX Best Practices with EasyEngine

Getting Started

#install easy-engine

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

#install nginx, php, mysql, postfix

ee stack install

#install WordPress on example.com

ee site create example.com --wpfc

Page 35: WordPress + NGINX Best Practices with EasyEngine

WordPress Multisite Handling

#multisite with subdirectory

ee site create example.com --wpfc --wpsubdir

#multisite with subdomain

ee site create example.com --wpfc --wpsubdom

Page 36: WordPress + NGINX Best Practices with EasyEngine

EasyEngine Demo

Page 37: WordPress + NGINX Best Practices with EasyEngine

EasyEngine Resources

Home : http://rtcamp.com/easyengine

Github : http://github.com/rtCamp/easyengine

Forum : http://community.rtcamp.com/category/easyengine/

Page 38: WordPress + NGINX Best Practices with EasyEngine

Q&A

mailto: [email protected]

or better, join the discussion on

http://community.rtcamp.com/