Upload
nginx-inc
View
1.322
Download
10
Embed Size (px)
Citation preview
WordPress-NGINX Best Practices
(With EasyEngine)
by Rahul Bansal (rtCamp)
WordPress-NGINX - Best practices
“If you can do it in NGINX, just do it in
NGINX!”
The Rule!
#1. nginx fastcgi-cache
Purpose
● Best solution for serving content to non-
logged in users
● Should be used instead full-page-cache from
WordPress plugin
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;
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
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; }
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; }
if ($query_string != "") {
set $skip_cache 1; }
# for http://example.com/?s=hello
if ($arg_s != "") {
set $skip_cache 0; }
Caching search result pages
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";
#2. NGINX substitution module
CDN & SSL Warning fix
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)
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
#3. pagespeed module
Reduce load time
● css/js minify & combine.
● search-replace URL for CDN
● on the fly image (lossless) compression
● lazy loading for images
pagespeed module
# 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
# 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
#4. Upstream Module
Load Balancer/Failover
upstream backend {
ip_hash;
server 1.1.1.1;
server 2.2.2.2;
server 2.2.2.2;
}
load balance mode
failover mode
upstream backend {
server 1.1.1.1 max_fails=3 fail_timeout=30s;
server 2.2.2.2 backup;
}
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
}
Backend NGINX Config
#gloabal config
set_real_ip_from 9.9.9.9;
real_ip_header X-Forwarded-For;
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
#5. Upstream mod with HHVM
Speed for logged in users
HHVM with PHP-FPM fallback
upstream php {
server 127.0.0.1:8000; #hhvm
server 127.0.0.1:9000 backup; #php-fpm
}
More Tricks
The list is endless!
#enable SSL cache
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
#enable spdy
server {
listen 443 ssl spdy;
}
SSL and spdy
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;
}
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;
}
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
Using 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?
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
WordPress Multisite Handling
#multisite with subdirectory
ee site create example.com --wpfc --wpsubdir
#multisite with subdomain
ee site create example.com --wpfc --wpsubdom
EasyEngine Demo
EasyEngine Resources
Home : http://rtcamp.com/easyengine
Github : http://github.com/rtCamp/easyengine
Forum : http://community.rtcamp.com/category/easyengine/