Nginx – mise en cache

Le billet suivant présente un manière simple et efficace d’optimiser un site dynamique avec la mise en cache de Nginx. Pour l’exemple il s’agira d’un site sous WordPress.

Il n’y a rien de neuf ici, c’est juste une reprise des informations que vous pouvez trouver un peu partout.

Par site dynamique, j’entends un site dont les pages sont constituées dynamiquement à partir de données en base et de scripts exécutés coté serveur (ici du php). C’est typiquement le fonctionnement de WordPress.

A l’opposé, un site statique est constitués d’un ensemble de fichiers qui sont transmis directement aux utilisateurs, comme des images ou des fichiers html/css/js/…

Comme c’est la spécialité de Nginx, servir des fichiers statiques, nous allons voir comment « transformer » notre site dynamique en site statique.
Si vous n’utilisez pas Nginx, cet article perd de son intérêt.

Le principe est simple et bien connu, on met en cache les pages générées dynamiquement.

Voici les directives importantes :

La zone de cache :

fastcgi_cache_path /run/shm/nginx_cache/1 levels=1:2 keys_zone=CACHE1:100m inactive=60m;
  • /run/shm est une zone montée en mémoire (ramfs) afin de limiter les accès disques
  • levels : c’est la structure des dossiers qui sera utilisée pour le cache
  • keys_zone : le nom de l’espace de cache et sa taille maximale
  • inactive : la durée de rétention d’un objet non utilisé, ici 60 minutes

La méthode de mise en cache :

fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

Les directives suivantes permettent d’activer ou de désactiver la mise en cache :

set $skip_cache 0;
set $skip_cache 1;

Un exemple d’appel au cache :

fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache CACHE1;
fastcgi_cache_valid 60m;

La directive suivante permet de purger tout ou partie du cache sous certaines conditions :

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

nb : le module fastcgi_cache_purge n’est pas intégré dans la version officielle de nginx (au moins en 1.9.x), mais il l’est dans celle fourni dans par Debian ou Dotdeb (1.8.x).

Pour WordPress, vous trouverez un plugin permettant de purger intelligemment le cache en cas de création/modification du contenu : Nginx Helper

Ensuite il faut jouer avec les « location » pour mettre ou non les pages en cache.

A titre d’exemple, voici un exemple de configuration pour WordPress :

fastcgi_cache_path /run/shm/nginx_cache/1 levels=1:2 keys_zone=CACHE1:100m inactive=60m;
server {
*:80;
server_name www.exemple.org;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

root /var/www;
index index.php;

location ~ /\. {
    deny  all;
    access_log off;
    log_not_found off;
}
set $skip_cache 0;
if ($request_method = POST) {
    set $skip_cache 1;
}
if ($query_string != "") {
    set $skip_cache 1;
}
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
    set $skip_cache 1;
}
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
}
location / {
    try_files $uri $uri/ /index.php?$args;
    expires 15d;
}
location ~ .php$ {
    try_files $uri /index.php;
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    fastcgi_cache CACHE1;
    fastcgi_cache_valid 60m;
}
location ~ /purge(/.*) {
    fastcgi_cache_purge CACHE1 "$scheme$request_method$host$1";
}
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
    expires max;
}
}

Vous pouvez bien entendu utiliser cette méthode pour tout type de site, pas seulement WordPress.

Source : rtCamp

Laisser un commentaire