Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm using W3 Total Cache and Nginx with Varnish, and I'm very happy with the speed. However, I noticed that when I schedule a post, the post doesn't get automatically posted when I'm a visitor. When I'm logged in as an admin and I reload the page it correctly posts the new content.

Varnish config (default.vcl)

#
# Varnish 3 configuration for Wordpress
#
# On Debian OS:  /etc/varnish/default.vcl
#
# Nicolas Hennion (aka) Nicolargo
#

# Set the default backend (Nginx server for me)
backend default {
    # My Nginx server listen on IP address 127.0.0.1 and TCP port 8080
    .host = "127.0.0.1";
    .port = "8080";
    # Increase guru timeout
    # http://vincentfretin.ecreall.com/articles/varnish-guru-meditation-on-timeout
    .first_byte_timeout = 300s;
}

# Forbidden IP ACL
acl forbidden {
    "41.194.61.2"/32;
    "192.54.144.229"/32;
}

# Purge ACL
acl purge {
    # Only localhost can purge my cache
    "127.0.0.1";
    "localhost";
}

# This function is used when a request is send by a HTTP client (Browser) 
sub vcl_recv {
    # Block the forbidden IP addresse
    if (client.ip ~ forbidden) {
            error 403 "Forbidden";
    }

    # Only cache the following sites
    #if ((req.http.host ~ "(blog.nicolargo.com)") || (req.http.host ~ "(blogtest.nicolargo.com)")) { 
    if ((req.http.host ~ "(blog.nicolargo.com)")) { 
        set req.backend = default; 
    } else { 
        return (pass); 
    }

    # Compatibility with Apache format log
    if (req.restarts == 0) {
        if (req.http.x-forwarded-for) {
                set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
     }

    # Normalize the header, remove the port (in case you're testing this on various TCP ports)
    set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");

    # Allow purging from ACL
    if (req.request == "PURGE") {
        # If not allowed then a error 405 is returned
        if (!client.ip ~ purge) {
            error 405 "This IP is not allowed to send PURGE requests.";
        }   
        # If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()
        return (lookup);
    }

    # Post requests will not be cached
    if (req.request == "POST") {
        return (pass);
    }

    # --- Wordpress specific configuration

    # Did not cache the RSS feed
    if (req.url ~ "/feed") {
        return (pass);
    }

    # Blitz hack
        if (req.url ~ "/mu-.*") {
                return (pass);
        }


    # Did not cache the admin and login pages
    if (req.url ~ "/wp-(login|admin)") {
        return (pass);
    }

    # Remove the "has_js" cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");

    # Remove any Google Analytics based cookies
    set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");

    # Remove the Quant Capital cookies (added by some plugin, all __qca)
    set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");

    # Remove the wp-settings-1 cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

    # Remove the wp-settings-time-1 cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");

    # Remove the wp test cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

    # Are there cookies left with only spaces or that are empty?
    if (req.http.cookie ~ "^ *$") {
            unset req.http.cookie;
    }

    # Cache the following files extensions 
    if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {
        unset req.http.cookie;
    }

    # Normalize Accept-Encoding header and compression
    # https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
    if (req.http.Accept-Encoding) {
        # Do no compress compressed files...
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
                remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
                set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
                set req.http.Accept-Encoding = "deflate";
        } else {
            remove req.http.Accept-Encoding;
        }
    }

    # Check the cookies for wordpress-specific items
    if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
        return (pass);
    }
    if (!req.http.cookie) {
        unset req.http.cookie;
    }

    # --- End of Wordpress specific configuration

    # Did not cache HTTP authentication and HTTP Cookie
    if (req.http.Authorization || req.http.Cookie) {
        # Not cacheable by default
        return (pass);
    }

    # Cache all others requests
    return (lookup);
}

sub vcl_pipe {
    return (pipe);
}

sub vcl_pass {
    return (pass);
}

# The data on which the hashing will take place
sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }

    # If the client supports compression, keep that in a different cache
        if (req.http.Accept-Encoding) {
            hash_data(req.http.Accept-Encoding);
    }

    return (hash);
}

sub vcl_hit {
    # Allow purges
    if (req.request == "PURGE") {
        purge;
        error 200 "Purged.";
    }

    return (deliver);
}

sub vcl_miss {
    # Allow purges
    if (req.request == "PURGE") {
        purge;
        error 200 "Purged.";
    }

    return (fetch);
}

# This function is used when a request is sent by our backend (Nginx server)
sub vcl_fetch {
    # For static content strip all backend cookies
    if (req.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico") {
        unset beresp.http.cookie;
    }

    # A TTL of 30 minutes
    set beresp.ttl = 1800s;

    return (deliver);
}

# The routine when we deliver the HTTP request to the user
# Last chance to modify headers that are sent to the client
sub vcl_deliver {
    if (obj.hits > 0) { 
        set resp.http.X-Cache = "cached";
    } else {
        set resp.http.x-Cache = "uncached";
    }

    # Remove some headers: PHP version
    unset resp.http.X-Powered-By;

    # Remove some headers: Apache version & OS
    unset resp.http.Server;

    return (deliver);
}

sub vcl_init {
    return (ok);
}

sub vcl_fini {
    return (ok);
}

nginx (examplesite.conf)

server {
    ## Your website name goes here.
    server_name examplesite.com www.examplesite.com;
    ## Your only path reference.
    root /var/www/examplesite.com;
    listen 8080;
    ## This should be in your http block and if it is, it's not needed here.
    index index.html index.htm index.php;
    ##set body size
    client_max_body_size 20M;


    include conf.d/drop;

        location / {
                # This is cool because no php is touched for static content
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        location ~ \.php$ {
            fastcgi_intercept_errors on;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass unix:/dev/shm/php-fpm-www.sock;


        }


# BEGIN W3TC Page Cache cache
location ~ /wp-content/w3tc/pgcache.*html$ {
    add_header Vary "Accept-Encoding, Cookie";
}
location ~ /wp-content/w3tc/pgcache.*gzip$ {
    gzip off;
    types {}
    default_type text/html;
    add_header Vary "Accept-Encoding, Cookie";
    add_header Content-Encoding gzip;
}
# END W3TC Page Cache cache
# BEGIN W3TC Browser Cache
gzip on;
gzip_types text/css application/x-javascript text/x-component text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
location ~ \.(css|js|htc)$ {
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1y;
log_not_found off;
}
location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
}
location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
}
# END W3TC Browser Cache
# BEGIN W3TC Page Cache core
rewrite ^(.*\/)?w3tc_rewrite_test$ $1?w3tc_rewrite_test=1 last;
set $w3tc_rewrite 1;
if ($request_method = POST) {
    set $w3tc_rewrite 0;
}
if ($query_string != "") {
    set $w3tc_rewrite 0;
}
if ($http_host !~ "examplesite.com") {
    set $w3tc_rewrite 0;
}
set $w3tc_rewrite3 1;
if ($request_uri ~* "(\/wp-admin\/|\/xmlrpc.php|\/wp-(app|cron|login|register|mail)\.php|\/feed\/|wp-.*\.php|index\.php)") {
    set $w3tc_rewrite3 0;
}
if ($request_uri ~* "(wp\-comments\-popup\.php|wp\-links\-opml\.php|wp\-locations\.php)") {
    set $w3tc_rewrite3 1;
}
if ($w3tc_rewrite3 != 1) {
    set $w3tc_rewrite 0;
}
if ($http_cookie ~* "(comment_author|wp\-postpass|wordpress_\[a\-f0\-9\]\+|wordpress_logged_in)") {
    set $w3tc_rewrite 0;
}
if ($http_user_agent ~* "(W3\ Total\ Cache/0\.9\.2\.4)") {
    set $w3tc_rewrite 0;
}
set $w3tc_ua "";
set $w3tc_ref "";
set $w3tc_ssl "";
set $w3tc_enc "";
if ($http_accept_encoding ~ gzip) {
    set $w3tc_enc _gzip;
}
set $w3tc_ext "";
if (-f "$document_root/wp-content/w3tc/pgcache/$request_uri/_index$w3tc_ua$w3tc_ref$w3tc_ssl.html$w3tc_enc") {
    set $w3tc_ext .html;
}
if ($w3tc_ext = "") {
  set $w3tc_rewrite 0;
}
if ($w3tc_rewrite = 1) {
    rewrite .* "/wp-content/w3tc/pgcache/$request_uri/_index$w3tc_ua$w3tc_ref$w3tc_ssl$w3tc_ext$w3tc_enc" last;
}
# END W3TC Page Cache core

}

How can I fix this? Thanks!

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

wp_schedule_event is only run when your site is visited and the scheduled time has past. If varnish is serving a non expired cached page then your visitor is not hitting WordPress.

Schedules a hook which will be executed by the WordPress actions core on a specific interval, specified by you. The action will trigger when someone visits your WordPress site, if the scheduled time has passed. See the Plugin API for a list of hooks.

Eventually when your cache expires or is invalidated your wp_cron should fire when varnish rebuilds the cache.

share|improve this answer
    
Ok, to workaround this problem I fire the wp-cron from a crontab every 15 minutes. However, it' not clearing the cache, even though I did configure varnish cache refresh in W3 Total Cache. Is there a way to do this manually in cron aswell? –  FLX Apr 17 '12 at 8:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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