I have setup nginx with caching in WordPress.

I am using the https://wordpress.org/plugins/nginx-helper/, however it seems the logged in page is being cached when it should not be (hence showing the logged in bar).

Some visitors who are not logged in (nor have any cookies/browser-cache) are seeing the logged in bar (if they click on anything within the bar it redirects them to login page).

enter image description here

In addition, when I click the purge cache button within WordPress, pages are still served and shown as XCache HIT... the only way to really purge is by rm -rf /dev/shm/nginx.

I do have the following modules installed:

nginx version: nginx/1.8.0
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' 
--with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log 
--error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body 
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi 
--with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module
--with-http_stub_status_module --with-http_realip_module 
--with-http_auth_request_module --with-http_addition_module
--with-http_geoip_module --with-http_gzip_static_module
--with-http_image_filter_module --with-http_spdy_module 
--with-http_sub_module --with-http_xslt_module

Any idea what is wrong with my config please?

user www-data;
worker_processes 4;
pid /run/nginx.pid;

events {
        worker_connections 1024;
        multi_accept on;

http {
        geoip_country /usr/local/share/GeoIP/GeoIP.dat;
        geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        client_max_body_size 300m;
        proxy_send_timeout 300;
        proxy_read_timeout 300;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

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

        gzip on;
        gzip_disable "msie6";

        # Upstream to abstract backend connection(s) for PHP.
        upstream php {

        include /etc/nginx/conf.d/*.conf;

        fastcgi_cache_path /dev/shm/nginx levels=1:2 keys_zone=WPCACHE:384m max_size=3072m inactive=480m;
        fastcgi_cache_key "$scheme$request_method$host$request_uri";

        server {
            server_name mysite.com;
            root /home/mysite/public_html/;
            index index.php;

            access_log /home/mysite/logs/access.log;
            error_log  /home/mysite/logs/error.log;

            fastcgi_cache_use_stale error timeout invalid_header http_500;
            fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

            # Rules to work out when cache should or should not be used
            set $skip_cache 0;
            # POST requests and urls with a query string should always go to PHP

            if ($request_method = POST) {
                set $skip_cache 1;

            if ($query_string != "") {
                set $skip_cache 1;

            # Don't cache uris containing the following segments
            if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
                set $skip_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 $skip_cache 1;

            location = /favicon.ico {
                log_not_found off;
                access_log off;

            location / {
                try_files $uri $uri/ /index.php?$args;

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

            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 php;

                fastcgi_cache WPCACHE;
                fastcgi_cache_valid 200 480m;

                fastcgi_cache_methods GET HEAD;
                fastcgi_cache_bypass $skip_cache;
                fastcgi_no_cache $skip_cache;

                #more_clear_headers Server; more_clear_headers "Pragma";
                add_header Z_LOCATION "PHP MAIN"; add_header URI $uri; # DEBUG
                add_header X-Cache $upstream_cache_status;

            location ~ /purge(/.*) {
                fastcgi_cache_purge WPCACHE "$scheme$request_method$host$1";

            location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|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;

            location = /robots.txt {
                access_log off;
                log_not_found off;

            location ~ /\. {
                deny  all;
                access_log off;
                log_not_found off;

That config looks very familiar - I posted most of it in another thread :) Alas it's missing an important part.

location = /wp-login.php {
  fastcgi_keep_conn on;
  fastcgi_intercept_errors on;
  fastcgi_pass   php;
  include        fastcgi_params;
  fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;

  # No caching
  more_clear_headers "Cache-Control";
  add_header Cache-Control "private, max-age=0, no-cache, no-store";
  more_clear_headers "Expires";

Also, the Nginx Helper just doesn't work to clear the cache. I spent AGES trying to make it work, but it just doesn't. I couldn't get the Nginx Cache plugin working either.

Nginx Cache Update

From @rafa in the comments: the problem is nginx-helper has a hard-coded path for the cache files to be under /var/run/nginx-cache, and the OP's config indicates the path /dev/shm/nginx for the cache files. I just changed my fastcgi_cache_path to the "correct" path, and nginx-cache works

  • Thanks Tim, a question for understanding and not criticism I very much appreciate your help... any reason this wasn't listed in your original post? Is it doing something different? I don't see that section on other nginx cache tutorials (i.e. nginx.com/blog/…) - clarification much appreciated. – morleyc Feb 7 '16 at 5:11
  • I would've posted parts of a config to illustrate a principle or how to fix a problem, rather than to say "set up your Nginx like this". Though it has pretty good comments because they're taken from my AWS/Nginx/Wordpress tutorial, which is coming out before too long... all my sites are live on AWS now, so it's just tiding up the tutorial. – Tim Feb 7 '16 at 8:10
  • A small comment regarding "nginx helper doesnt work to clear the cache"; the problem is nginx-helper has a hard-coded path for the cache files to be under /var/run/nginx-cache, and the OP's config indicates the path /dev/shm/nginx for the cache files. I just changed my fastcgi_cache_path to the "correct" path, and nginx-cache works. – Rafa Dec 31 '19 at 13:16
  • Thanks @Rafa , I'll have a try of that myself sometime and update my post when I've confirmed it. – Tim Dec 31 '19 at 21:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.