amuck-landowner

Nginx + Wordpress with caching

jcaleb

New Member
I use nginx for hosting wordpress, but I wanted to take advantage of caching feature of nginx. I tried to look for the config to make it work. So I tried many tutorial, combined some when it worked, the output is below.

I assume you have fresh install of nginx, first edit nginx config to put in cache settings.


pico /etc/nginx/nginx.conf

and right after the line "http {" put the following:


fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:10m inactive=50m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;

create the folder global


mkdir /etc/nginx/global
Create /etc/nginx/global/restrictions.conf with the following contents:


# Global restrictions configuration file.
# Designed to be included in any server {} block.</p>
location = /favicon.ico {
log_not_found off;
access_log off;
}

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
deny all;
}

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}

# Make sure files with the following extensions do not get loaded by nginx because nginx would display the source code, and these files can contain PASSWORDS!
location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_
{
return 444;
}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
return 444;
access_log off;
log_not_found off;
}

#nocgi
location ~* \.(pl|cgi|py|sh|lua)\$ {
return 444;
}

#disallow
location ~* (roundcube|webdav|smtp|http\:|soap|w00tw00t) {
return 444;
}

Create /etc/nginx/global/wordpress.cache.conf with the following contents:


#fastcgi_cache start
set $no_cache 0;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $no_cache 1;
}
if ($query_string != "") {
set $no_cache 1;
}

# Don't cache uris containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
set $no_cache 1;
}

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $no_cache 1;
}

#note location{] block is simple now as caching is done on nginx's end
location / {
try_files $uri $uri/ /index.php?$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(js|css|swf|xml|txt|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_cache WORDPRESS;
#fastcgi_cache_valid 5m;

fastcgi_cache_valid 200 302 60m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 60m;
}

Create /etc/nginx/global/wordpress.conf with the following contents:


# WordPress single blog rules.
location / {
try_files $uri $uri/ /index.php?$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(js|css|swf|xml|txt|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
When I want to host a website, say jon.com, I will just create /etc/nginx/sites-enabled/jon.com.conf with the ff. content if I want wordpress with caching


server {
listen 80;
server_name jon.com www.jon.com;

access_log /var/log/nginx/jon.com.access.log;
error_log /var/log/nginx/jon.com.error.log;

root /home/jon/sites/jon.com;
index index.php index.htm index.html;

include global/restrictions.conf;
include global/wordpress.cache.conf;
}

And the following content if I dont want caching

Code:
server {
    listen 80;
    server_name jon.com www.jon.com;

    access_log /var/log/nginx/jon.com.access.log;
    error_log /var/log/nginx/jon.com.error.log;

    root /home/jon/sites/jon.com;
    index index.php index.htm index.html;

    include global/restrictions.conf;
    include global/wordpress.conf;
}
 
Last edited by a moderator:

jcaleb

New Member
After trying above, I test using siege or ab, cant remember.  But it seems at least 20x faster, or more.  Just cant remember.  So long ago, Im just digging up notes.
 

vanarp

Active Member
Thank you for the detailed tutorial. Two questions :


- does it work for nginx + php-fpm setup ?


- is this a replacement for using W3 Total Cache like plugin ?
 

jcaleb

New Member
yes, it is assumed php-fpm because of fastcgi_pass 127.0.0.1:9000; in the 2 last conf files. I am lazy to put config using socket, as my sites are not that busy.

yes something like a replacement for w3 total cache. Because it cache all page if visitor is not a logged in user. i used 60 minutes above before a cached page becomes stale.
 

Mun

Never Forget
This is actually not a great setup if you get tons of comments, as the comments won't come into effect for possibly 1 hour. quick cache + a 1 min cache on valid outputs might be better.
 

Abdussamad

New Member
This is actually not a great setup if you get tons of comments, as the comments won't come into effect for possibly 1 hour. quick cache + a 1 min cache on valid outputs might be better.
If you use the Nginx helper plugin and follow the tuts linked on that page you won't have this problem. That is because the plugin invalidates the cache for pages with new content. If someone posts a comment the cached copy is flushed with a new one containing the latest comment. Similarly if you post a new blog post or make other changes the relevant pages are updated.

It is not perfect. For example if you remove or add widgets it won't update the site immediately. But generally speaking you have the same problems with other caching plugins like WP Super Cache. And these plugins do the caching in php which is slower than doing it in compiled C code i.e. Nginx. Also all these plugins are open source so you can contribute and improve them. The Nginx helper plugin authors are not particularly nice but the code is there and you can fork it.
 

Abdussamad

New Member
I wonder the same. Is hurt to run multiple caching? Via nginx conf + plugin on WP.
Yes it is a replacement. IT is for those who have root access and want extreme performance. Multiple levels of the same type of caching will only increase complexity and make it harder to diagnose problems. Also it might reduce performance.
 

jcaleb

New Member
@eva2000 it is just a simple guide, as i am not really expert in system admin work.  and my needs is basic.  the personal sites i hosts are just fairly static (just ocasional posts) and i dont allow comments in my blog =)
 

eva2000

Active Member
Simple but useful guide.. sure folks here with more fastcgi_cache experience could add their input too :D
 

eva2000

Active Member
Anyone using fastcgi_cache method come across the problem outlined at http://centminmod.com/nginx_configure_wordpress.html#fastcgicache ?

a minor issue when logged into Wordpress Admin Dashboard, that previewing new post links result in 404 not found errors. A workaround for now is open preview link in new tab/window for browser and on preview link (404) error page, clear cookies and refresh page. That sometimes allows admin to still be logged in but see preview link
As such thanks to a fellow Centmin Mod user, came across an alternative cache method using WP-FFPC plugin http://vpsboard.com/topic/1273-centmin-mod-nginx-wordpress-wp-ffpc-plugin-setup-ngx-pagespeed/ :)
 
Top
amuck-landowner