Tag Archives: nginx

WordPress caching with nginx

As a part of my friend @zenkay post on his blog here it is a simple but efficient nginx configuration for proxying and caching an Apache + WordPress installation.

Assuming that:

  • nginx and Apache are on different nodes: if nginx and Apache are on the same machine is highly advised to serve static files directly from nginx;
  • static files expire header is managed by Apache (through mod_expires); if static stuff is served directly you need to specify the expire through nginx;
  • you have installed the WordPress Nginx proxy cache integrator;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
server {
    # Listen IPv6 and IPv4 socket
    listen       [::]:80; #on Linux this means both IPv4 and IPv6
    # Name-based virtualhosts
    server_name  *.mydomain.com mydomain.com;
 
    # Add Cache-Status debug header on replies
    add_header X-Cache-Status $upstream_cache_status;
 
    # Set the vhost access-log
    access_log  /var/log/nginx/access-mydomain.log  main;
 
    location / {
 
        # Skip^1 caching variable init
        set $nocache 0;
        # Bypass^2 caching variable init
        set $purgecache 0;
 
        # Bypass^2 cache on no-cache (et al.) browser request
        if ($http_cache_control ~ "max-age=0")
            { set $purgecache 1; }
        if ($http_cache_control ~ "no-cache")
            { set $purgecache 1; }
        # Bypass^2 cache with custom header set on request
        if ($http_x_cache_purge ~* "true")
            { set $purgecache 1; }
        # Skip^1 caching when WordPress cookies are set
        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" )
            { set $nocache 1; }
 
        # Cache pool
        proxy_cache             proxy-one;
        # Bypass^2 cache when $purgecache is set to 1.
        # Bypass means that content is served fresh and the cache is updated
        proxy_cache_bypass      $purgecache;
        # Skip^1 caching when $nocache is set to 1
        # Do not cache when browsing frontend as logged user
        proxy_no_cache          $nocache;
        # Define the cache resource identifier. Be careful to add $nocache
        proxy_cache_key         "$scheme$http_host$request_uri$args$nocache";
        proxy_connect_timeout   10;
        proxy_read_timeout      10;
        # use stale cache on backend fault
        proxy_cache_use_stale   error timeout invalid_header updating http_500 http_502 http_503 http_504;
        proxy_cache_valid       200 302 15m;
        proxy_cache_valid       404 1m;
        proxy_set_header        Host             $host;
        proxy_set_header        X-Real-IP        $remote_addr;
        proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_pass              http://apache_remote_ip;
    }
 
    location ~* \/blog\/wp\-.*\.php|\/blog\/wp\-admin {
        proxy_cache             off;
        proxy_pass              http://apache_remote_ip;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}

1^ see: http://wiki.nginx.org/HttpProxyModule#proxy_no_cache
2^ see: http://wiki.nginx.org/HttpProxyModule#proxy_cache_bypass

lighttpd front controller

Oramai è prassi diffusa l’utilizzo di un front controller nelle applicazioni web. Per implementarlo correttamente è necessario che il web server effettui delle rewrite dell’URL.

Se si utilizza Apache non è un grosso problema poiché quasi tutti i software che richiedono l’esecuzione di una o più rewrite contengono il file .htaccess pronto all’uso.

Per nginx c’è l’utilissima funzione try_files

try_files $uri $uri/ /index.php?url=$uri;

Per lighttpd? E’ possibile implementare anche in lighttpd una funzione simile alla try_files di nginx tramite una rewrite

url.rewrite-once = ( "^/(.*)\.(.*)" => "$0", "^/([^.]+)$" => "/index.php?url=$1" )

Questa regola, alla pari di try_files, verifica che la risorsa richiesta esista: nel caso di esito positivo non avviene la rewrite, mentre se non esiste l’uri viene passata al front controller.

Per poterla utilizzare il modulo mod_rewrite deve essere caricato

server.modules  += ( "mod_rewrite" )