nicolargo / varnish-nginx-wordpress

A "simple" Varnish ang NGinx configuration for a Wordpress blog
307 stars 85 forks source link

Fail to login to wordpress #29

Open dofrance opened 9 years ago

dofrance commented 9 years ago

Hi, Thank you for your great Varnish4 config, my frontend page run really fast but when I try to login to Wordpress at login page, it fail with this

Error 503 Backend fetch failed Backend fetch failed Guru Meditation: XID: 32788 Varnish cache server

I use Nginx as backend server on port 8080 for HTTP request. Here is my Varnish log: << BeReq >> 32858

<< Request >> 32857

Oyabi commented 9 years ago

Hi, can you post your varnish configuration please ? Have you these lines ?

[...]
    # Did not cache the admin and login pages
    if (req.url ~ "/wp-(login|admin)") {
        return (pass);
    }
[...]
    # Only allow cookies to be set if we're in admin area
    if (beresp.http.Set-Cookie && bereq.url !~ "^/wp-(login|admin)") {
            unset beresp.http.Set-Cookie;
        }
[...]

Regards.

dofrance commented 9 years ago

Hi Oyabi, I did have those lines because I copy entire of your conf from https://github.com/nicolargo/varnish-nginx-wordpress/blob/master/varnish/varnish4-wordpress

Oyabi commented 9 years ago

Have you made any change to the config ? Can you post your config please ? What's your varnish version ? (varnishd -V) When you curl/wget 127.0.0.1:8080, can you confirm that you get your site ? Restart nginx, then restart varnish, and retest. What's your OS ? I read that SElinux can cause problem.

Regards.

dofrance commented 9 years ago

My OS is Ubuntu server 14.04 varnishd -V varnishd (varnish-4.0.3 revision b8c4a34) Copyright (c) 2006 Verdens Gang AS Copyright (c) 2006-2014 Varnish Software AS

Here's my varnish config

vcl 4.0;

# Default backend definition. Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "8888";
}

backend exciter {
        .host = "127.0.0.1";
        .port = "8080";
     .connect_timeout = 30s;
     .between_bytes_timeout = 15s;
     .first_byte_timeout = 300s;
}

acl purge {
    "localhost";
    "127.0.0.1";
}

import std;
include "inc/xforward.vcl";
include "inc/bigfiles.vcl";
include "inc/purge.vcl";

sub vcl_recv {

    # 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.method == "PURGE") {
        # If not allowed then a error 405 is returned
        if (!client.ip ~ purge) {
            return(synth(405, "This IP is not allowed to send PURGE requests."));
        }   
        # If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()
        return (purge);
    }

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

# ---------------------- /BACKEND Routing-------------------- #

    if (req.http.host == "exciter.com") {
       set req.backend_hint = exciter;
    }

# ---------------------- /BACKEND Routing-------------------- #

# ---------------------- /WORDPRESS SPECIFIC CONFIG -------------------- #
    # 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);
    }

    if (req.http.Cookie ~ "wordpress_logged_in_") {
        return (pass); # varnish 4
    }   

    if (req.http.X-Requested-With == "XMLHttpRequest") {
      return (pass);
    } 
     # Do not cache the WooCommerce pages
     ### REMOVE IT IF YOU DO NOT USE WOOCOMMERCE ###
    if (req.url ~ "/(cart|my-account|checkout|addons|/?add-to-cart=)") {
            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|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)$") {
                unset 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 {
            unset req.http.Accept-Encoding;
        }
    }

    # --- 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 (hash);
}

sub vcl_pipe {
    # Force every pipe request to be the first one.
    # https://www.varnish-cache.org/trac/wiki/VCLExamplePipe
    return (pipe);
}

sub vcl_pass {
    return (fetch);
}

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 (lookup);
}

sub vcl_backend_response {
# Remove some headers we never want to see
    unset beresp.http.Server;
    unset beresp.http.X-Powered-By;

    # For static content strip all backend cookies
    if (bereq.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico") {
        unset beresp.http.cookie;
    }

    # Only allow cookies to be set if we're in admin area
    if (beresp.http.Set-Cookie && bereq.url !~ "^/wp-(login|admin)") {
            unset beresp.http.Set-Cookie;
        }

    # don't cache response to posted requests or those with basic auth
    if ( bereq.method == "POST" || bereq.http.Authorization ) {
            set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
        }

        # don't cache search results
    if ( bereq.url ~ "\?s=" ){
        set beresp.uncacheable = true;
                set beresp.ttl = 120s;
                return (deliver);
    }

    # only cache status ok
    if ( beresp.status != 200 ) {
        set beresp.uncacheable = true;
                set beresp.ttl = 120s;
                return (deliver);
    }

    # A TTL of 24h
    set beresp.ttl = 24h;
    # Define the default grace period to serve cached content
    set beresp.grace = 30s;

    return (deliver);
}

sub vcl_deliver {

    # Remove unnecessary headers
    unset resp.http.Server;
    unset resp.http.X-Powered-By;
    unset resp.http.X-Varnish;
    unset resp.http.Via;

    # DIAGNOSTIC HEADERS
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
    return (deliver);
}

sub vcl_init {
    return (ok);
}

sub vcl_fini {
    return (ok);
}

Here's my nginx conf

server {
    listen 127.0.0.1:8080;
    root /var/www/exciter;

    index index.php index.html index.htm;

    server_name exciter.com;

       location / {
                try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        error_page 404 /404.html;

        location = /50x.html {
                root /usr/share/nginx/html;
        }

    location ^(.*)/uploads/pdf/(.*)/(.*).pdf(.?) {
        allow all;
    }

    # STATICS FILES
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
                #fastcgi_read_timeout 300;
        }
}

Thank you so much!

Oyabi commented 9 years ago

That's seem correct. Try this : http://serverfault.com/a/616663/215569 You must login in varnish user, or other user if varnish user don't have shell, and try to wget/curl 127.0.0.1:8080.

When you restart varnish and nginx, did you get some error ?

dofrance commented 9 years ago

There's no error for Nginx and Varnish log. I restart services and also restart the server :D I did Curl and the front end of website is coming. But when I try to login, there is no hit to the backend like Varnish log I posted!

Oyabi commented 9 years ago

Sorry but i don't know what cause that. Maybe try to change

backend default {
    .host = "127.0.0.1";
    .port = "8888";
}

by

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
dofrance commented 9 years ago

It Rock now! My mistake for old default stuff You're great!

dofrance commented 9 years ago

Uh, Oh Seem like, Add to cart button of my Woocomerce not working properly. I add something to cart, but it not go to cart!

Oyabi commented 9 years ago

Hum maybe an upgrade of woocommerce. Check the link respect this syntax :

if (req.url ~ "/(cart|my-account|checkout|addons|/?add-to-cart=)") {
            return (pass);
}

If it's not the case, add it. ;) So you get something like that:

if (req.url ~ "/(cart|my-account|checkout|addons|YOUR ADD HERE|/?add-to-cart=)") {
            return (pass);
}
dofrance commented 9 years ago

The cart still not work after I put exciter.com into Your ADD HERE what about if I have multiple backend

Oyabi commented 9 years ago

Hum, it's not really that, you can remove your add. I do not use myself woocommerce so my knowledge are limited. Maybe they upgrade the way to add item to cart. Try to add that (like here http://docs.woothemes.com/document/configuring-caching-plugins/):

if ( req.url ~ "\?add-to-cart=" ) {
 return (pass);
 }
dofrance commented 9 years ago

Sadly, I already try, restart varnish and nginx but it still not work Thank you for your help!

Oyabi commented 9 years ago

Sorry, but I have no more idea. Maybe try to post on woocommerce forum. :( Keep me informed. ;)

++

ablears commented 7 years ago

In vcl_recv, try

# Do not cache the WooCommerce pages
    if (req.url ~ "/(cart|my-account|checkout|addons|/?add-to-cart=)") {
      return (pass);
    } 

# don't cache ajax requests
if (req.http.X-Requested-With == "XMLHttpRequest") {
  return (pass);
}

if (req.http.cookie) {
  if (req.http.cookie ~ "(wordpress_|wp-settings-|wp_|woo_|woocommerce_)") {
      return(pass);
  } else {
    unset req.http.cookie;
  }
}

In vcl_backend_response I have:

if ( bereq.method == "POST" || bereq.http.Authorization ) {
  set beresp.uncacheable = true;
  set beresp.ttl = 120s;
  return (deliver);
}

if ( (!(bereq.url ~ "(wp-login|wp-admin|cart|checkout|transaction-results|my-account|product)")) ) {
  unset beresp.http.set-cookie;
  set beresp.ttl = 1h;
}

with this, Woo works fine using Varnish 4