Updated Varnish WordPress VCL

THIS VARNISH CONFIG HAS BEEN UPDATED AND IS AVAILABLE HERE

I have been tweaking a varnish vcl config for WordPress for quite some time and I wanted to share it..  Thanks to everyone(especially DocWilco)  in #varnish on Linpro IRC for helping

Features:

  1. Load balancing
  2. Probing
  3. Does not cache wp-admin
  4. Puts all uploads/content requests onto one server
  5. Purging
  6. Long timeout for file uploads
  7. XML RPC support
  8. Custom 404 and 500 message
  9. Forwards user IP address for comments

First of all.. Let’s define some backends..

// BACKEND CONFIGS
backend server1 {
  .host = "server1.example.com";
  .port = "8080";
  .probe = {
                .url = "/";
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
// we include time outs so uploads don't time out
 .connect_timeout = 600s;
 .first_byte_timeout = 600s;
 .between_bytes_timeout = 600s;
}

backend server2 {
  .host = "server2.example.com;
  .port = "8080";
  .probe = {
                .url = "/";
                .interval = 5s;
                .timeout = 1 s;
                .window = 5;
                .threshold = 3;
  }
// we include time outs so uploads don't time out
 .connect_timeout = 600s;
 .first_byte_timeout = 600s;
 .between_bytes_timeout = 600s;
}

// define round-robin for backends
director cluster round-robin {
        {.backend = server1;}
        {.backend = server2;}
}

// set the servers wordpress can purge from
acl purge {
        "server1.example.com";
        "server2.example.com";
}

sub vcl_fetch {
 if (req.http.host ~ "ourdomain.com"
     || req.http.host ~ "ourotherdomain.com"
// don't cache wp-admin ever cause that's not cool
     && req.url !~ "wp-admin")
{
// we cache these domains for 8 hours unless they are purged.
        set beresp.ttl = 8h;
        set beresp.grace = 600s;
// don't cache 404 or 500 errors
        if (beresp.status == 404 || beresp.status >= 500) {
                  set beresp.ttl = 0s;
        }
}
// tell all of the files to use server1
if (req.url ~ "files") {set req.backend = server;set beresp.ttl = 8h;}
}

sub vcl_recv {
// Purge WordPress requests for purge
  if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url == " req.url " && req.http.host == " req.http.host);
                error 200 "Purged.";
        }

// forward the client IP so comments show up properly
set req.http.X-Forwarded-For = client.ip;

// let server2 handle all feeds
    if (req.url ~ "/feed/")
    {set req.backend = server2;}

// server1 must handle file uploads
    if (req.url ~ "media-upload.php"
    || req.url ~ "file.php"
    || req.url ~ "async-upload.php")
    {set req.backend = server1;return(pass);}

// server1 can serve all files.
    if (req.url ~ "/files/")
    {set req.backend = server1;}

// do not cache xmlrpc.php
    if (req.url ~ "xmlrpc.php")
    {return(pass);}

// strip cookies from xmlrpc
    if (req.request == "GET" && req.url ~ "xmlrpc.php")
    remove req.http.cookie;return(pass);}

// caching these files is fine
if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|lzma|tbz)(\?.*|)$") {
            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;
        }
}

// Remove cookies and query string for real static files
    if (req.url ~ "^/[^?]+\.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.*|)$") {
       unset req.http.cookie;
       set req.url = regsub(req.url, "\?.*$", "");
    }

// Remove cookies from front page
    if (req.url ~ "^/$") {
       unset req.http.cookie;
    }

// if the request is for our domain and not for wp-admin then load balance it to a server that is responding or send it to server1
if (req.http.host ~ "ourdomain.com"
    || req.http.host ~ "ourotherdomain.com"
    && req.url !~ "wp-admin")
{
        set req.http.X-Forwarded-For = client.ip;
        set req.backend = cluster;
        } else {
        set req.http.X-Forwarded-For = client.ip;
        set req.backend = server1;
}

// Custom error message
sub vcl_error {
if(obj.status == 404) {
        set obj.ttl = 0s;
  set obj.http.Content-Type = "text/html; charset=utf-8";
    synthetic {" <!--?xml version="1.0" encoding="utf-8"?-->

    "} obj.status " " obj.response {"
</pre>
<div style="background-color: white;"><center>
 <img src="http://whatever.com/heavyload.jpg" alt="" width="600px" /></center>
<h1>This page is unavailable</h1>
If you are seeing this page, either maintenance is being
performed or you are trying to access a file that doesn't exist. Please <a href="http://whatever.com/contact.html">contact us</a> if you believe this is an error
<h2>Error "} obj.status " " obj.response {"</h2>
"} obj.response {" on server "} req.backend {"
<address><a href="http://whatever.com/">Us.</a></address></div>
<pre>
  "};
    return (deliver);
error 404 "Not found";
 }
else
{
    set obj.http.Content-Type = "text/html; charset=utf-8";
    synthetic {" <!--?xml version="1.0" encoding="utf-8"?-->  
  
    "} obj.status " " obj.response {"
  

</pre>
<div style="background-color: white;"><center>
 <img src="http://whatever.com/heavyload.jpg" alt="" width="600px" /></center>
<h1>This website is unavailable</h1>
If you are seeing this page, either maintenance is being
performed
 or something really bad has happened. Try returning in a few
minutes. If you still see this error in a few minutes please <a href="http://whatever.com/contact.html">contact us</a>
<h2>Error "} obj.status " " obj.response {"</h2>
"} obj.response {" on server "} req.backend {"
<address><a href="http://whatever.com/">Us.</a></address></div>
<pre>
  "};
    return (deliver);
}
}

How to put the latest CBBC news on your WordPress blog

Step 1. Log into your blog
Step 2. Click Appearance-> Widgets
Step 3. Drag RSS over to your sidebar.
Step 4. Paste http://newsrss.bbc.co.uk/rss/cbbc_news/homepage/rss.xml in where it asks for RSS feed URL
Step 5. Give the widget a title. *optional

Note: PrimaryBlogger users can just drag the CBBC Widget onto their sidebar.

Moving schools to IPv6

I have a unique position when it comes to moving schools to IPv6 in that I work with a technical support team, a hosted web services team and an internet reseller team so if you think about the connectivity “bridge” then we cover all bases.  When I refer to the bridge I mean we are responsible for the request from a web browser all the way through the web service servicing that request.

What is IPv6?

So as far as I see it we have a few major considerations and questions to ask and these are…

Do our school routers support IPv6?

Some of our schools have connectivity from RBCs and some from our resell Internet connectivity, it is much easier for us to work with our resell partners to enable IPv6 as our resell partners advocate moving towards IPv6 as they have an interest in not running out of IPv4 addresses.  There is no doubt the move towards IPv6 will require collaboration between different internal departments and different ISPs.

Do our school wireless access points care about IPv6?

Nearly all of the schools we work with have recently refreshed their wireless networks with either Cisco or Meru wireless solutions that we can be confident will properly support IPv6.  You might not think an AP support of IPv6 is important but it’s the basics such as configuring the device out of the box or IPv6 DHCP client support that can sting you later.  Although APs don’t do any routing it is still important the AP & Management system are IPv6 ready and configured.

Do our school laptop/pc/netbook devices support IPv6?

The vast majority of client devices in schools will support IPv6 out of the box however we will need to get our hardware inventory tool to push a report letting us know which devices don’t.  If the device doesn’t support IPv6 it is likely that the device will just remain on IPv4 until it is eventually phased out so it doesn’t really even matter so much.

Do our web services host names resolve to IPv6 address(as well as IPv4)?

Because we use round robin DNS on a lot of our web services we delayed implementing IPv6 however we aim to have this done before June the 1st which is world IPv6 day.

Remote access and network monitoring

Our remote access all works over IPv4 addresses so we may need to change this but with less than 100 users currently using the service we can worry about this bridge if/when we get there.  Personally I’m not a big fan of schools remoting into their school for security reasons but I understand sometimes it is a necessity although in the future I doubt this will be as predominant although this will require a restructure of SIMS/CMIS licensing models.

How do we alter Windows DHCP?

The majority of the schools use Microsoft Windows DHCP for issuing IPv4 addresses at current, we will need to alter the scope and ensure we are pushing IPv6 addresses.  This video shows the process involved in Server 2008 to do this.  We are constantly moving schools onto server 2008.  Note: If your technical support provider recommends Server 2003 please show them this page.

What other work does our technical support team need to do?

I think we need to sit down and discuss this and over time we will update this page.

What time-scale should we be looking at for completed IPv6 deployments?

I think aiming to get all of our schools IPv6 ready by mid 2012 should be okay.

Enhanced by Zemanta

What the last 4 days have tought me.

Disclaimer: These are my own words and do not reflect the view of my employer.

Some teachers are really supportive.  Huge thanks to @pimmsSmith, @LouMeethongsai, @janwebb21, @idletim, @deputymitchell, @enomilie, @purplelady1979, @anne_neal, @whorwe, @sraff79, @missbrownsword and @primaryt for your support and help.  The fact that you all got in touch asking for help and tested logins is great, we need testers just as much as we need developers or system admins so my hat goes off to you..

Some teachers are real not quite as nice (actually just one). Even though PrimaryBlogger is a free service I got an email saying “how disappointed they were with the support.”  To this teacher I remind you that PrimaryBlogger is unblocked in every UK LA, allows embed, open source, doesn’t enforce HTTPS only, spam free, ad free, not publicly funded and each blog post is reviewed by a CRB checked human from Primary Technology.  To combat this I think a community approach is needed, a wikipedia model of moderators should help.

PrimaryBlogger is as a service is spread across multiple servers and sites and isn’t run by monkeys or unskilled professionals, it takes a lot of expertise to deliver a scaled WordPress deployment.  Now you probably don’t care about how big it is but the fact is if we were selling PrimaryBlogger at £200 a school per year we would be making £400,000 a year, pretty good money right but that would mean the community wouldn’t grow and that would suck.  PrimaryBlogger will remain as a free blog service, last year we made £100 in total in sales of domains and additional storage purchases.   We thrive from the success of school blogs and we are rewarded by “inbound links” which in turn allows us to promote other Primary Technology products.  I have to justify the cost of PrimaryBlogger to our sales director and I do it based on the amount of respect it gets us inside of the teaching community, something not easily bought and something we don’t take for granted.

WordPress is open source and free and there are a number of hosts you can move your blog to.  I suggest everyone periodically backs their blog up anyway.  It’s really easy to do.  Tools -> Export..

If you really want to help PrimaryBlogger, buy a domain for your blogs through us, it’s only £50 per year and it will be an improvement to your blog.  I would like to employ someone full time to work on it and to build a community so if we can sell 400(one fifth of the # of blogs on PrimaryBlogger) domains that is one persons full time wage covered.  It would be way better though if we can encourage a community to become vocal and over the next few months that will be my goal.

I also want to comment quickly about how all of our findings/problems were put into the public domain.  How many other companies do you know that show you their inner workings and explain why a problem came about, how it was resolved and who resolved it?

So to reflect on what I have learned:

  1. Always trim old/stale blogs from the database
  2. Tell teachers that they are out of order if they are out of order
  3. Don’t do any development work on a live server the day before we’re due to have all of our staff on holiday
  4. Give PrimaryBlogger’s (and our other services) a community site they can go to to share experiences and knowledge
  5. We as a community need to discuss the benefits of having a blog site that has blogs with “search engines disabled”

PrimaryBlogger is all about giving school pupils and teachers a voice, we want you to be heard.