FullPage Caching für WordPress

Nginx – PHP-FPM und W3TotalCache

An dieser Stelle hatte ich eine kleine Artikelreihe zum Thema „Speedranking für WordPress“ gestartet.
Heute möchte ich einen alternativen Weg aufzeigen, der zu einem ähnlichen, in Summe jedoch sicherlich besseren Ergebnis führt, da wesentlich weniger Komponenten zusammen funktionieren müssen.

Der Fairness halber muss man als Präambel vorausschicken, dass ich alle meine relevanten Webseiten inzwischen auf HTTP2 umgestellt habe; somit ergibt sich „per se“ ein Plus an Geschwindigkeit – zumindest für Browser die HTTP2 unterstützen.
Zum Thema „HTTP2“ werde ich in Bälde hier auf dem WP-Loft Blog ein wenig mehr erzählen.

Aber zurück zum Thema dieses Beitrages: FullPage Caching für WordPress mit Nginx – PHP-FPM und W3TotalCache am Beispiel meiner 365-Tage-Fotoprojektseite.

Schaubild der bisherigen technischen Umsetzung

Nginx - Varnish - Apache Aufbau

Somit waren für eine optimierte WordPress-Installation drei „Server-Layer“ notwendig, die zu jeder Zeit fein granular auf einander abgestimmt sein mussten.
Ein nicht unerheblicher Aufwand, zudem Varnish einfach zu installieren, aber diffizil zu konfigurieren ist.

So möchte ich an dieser Stelle gerne Steve Jobs, oder war es Leonardo da Vinci (?),  zitieren:

„Simplicity is the ultimate sophistication“
(„Einfachheit ist die höchste Form der Raffinesse!“)

Es geht also „raffinierter“ !

Schaubild der neuen technischen Umsetzung

Cooool ! 

  • Kein HTTP / HTTPS – Mix mehr
  • Nur noch zwei „Server-Layer“ anstatt drei
  • Einfacher zu konfigurieren, daher übersichtlicher

Gut, man muss daran denken, die Funktionalität einer „Apache .htaccess Funktionalität“ in eine Nginx-Konfiguration  zu überführen; es wird sich jedoch zeigen, dass das nicht weiter problematisch ist.
So weit, so gut – oder Butter bei die Fische: Wie ist das Ganze nun in Konfiguration-Details umgesetzt ?

Die Umsetzung im Detail

Ausgehend von einem Ubuntu / Debian Derivat

1. Installation und Konfiguration  von PHP-FPM

Sofern nicht schon auf dem Server vorhanden installiert man PHP-FPM mittels

sudo apt-get install php5-fpm

Per default wird damit ein „FastCGI Process Manager“ installiert der auf einem Linux-Socket läuft:

foo@whatever:/var/run# ls -l | grep php5
-rw-r--r-- 1 root     root        5 Dez  1 17:16 php5-fpm.pid
srw-rw---- 1 www-data www-data    0 Dez  1 17:16 php5-fpm.sock
root@lvps91-250-113-206:/var/run#

Danach schauen wir in der /etc/php5/fpm/php.ini Datei nach, ob der Wert für cgi.fix_pathinfo auf „0“ steht:

; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=0

2. Konfiguration des Nginx-Vhosts für PHP-FPM

       
...
 # PHP-FPM und W3total Cache Gedoehns
 root /var/www/htdocs/365-tage-fotoprojekte.de;
 index index.php
....
 location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
...

Testen ob die Konfiguration korrekt ist, und danach die neue Nginx-Konfiguration laden:

nginx -t && service nginx reload

That’s all …
… wie das war es schon ?
Nicht ganz!

FullPacge Cache mit W3Total Cache

Oder: das Salz in der Suppe

Das W3TotalCache-Plugin bringt ein paar sehr nette (!) Features mit.
Zwei davon werden wir im Folgenden benutzen:

  • Den Page-Cache
  • Die „Auto-Nginx-Configuration

1. Benutzen des Page-Cache auf „Platte“

Dieses Feature macht meiner Meinung nach nur Sinn, wenn man einen Server mit SSD-Platte, oder ein entsprechend gemountetes temporäres Filesystem dafür benutzen kann.
Man geht also in die Einstellungen des W3TotalCache-Plugins und stellt den Page-Cache wie folgt ein:

In der Folge legt das W3TotalCache-Plugin im Dokument-Root der entsprechenden WordPress-Installation unter

/pfad/zur/WordPress/Installation/wp-content/cache

einen Unterordner mit dem Namen „page_enhanced“ an. In diesem Pfad speichert das Cache-Plugin alle aufgerufenen WordPress Seiten als fertig gerenderte *.html Datei ab.
Spannend wird das Ganze, wenn man in der Nginx-Vhost Konfiguration folgendes ergänzt:

        location / {
                try_files /wp-content/cache/page_enhanced/${host}${cache_uri}_index.html $uri $uri/ /index.php?$args ;
        }

Mit dieser Zeile sieht der Nginx nach, ob es zu einer aktuell angefragten WordPress-Seite bereits eine aktuelle und fertig gerenderte HTML Datei gibt. Wenn ja, so wird diese direkt ausgeliefert ohne

  1. den PHP-FPM Server zu bemühen
  2. Anfragen an die MySQL-Datenbank zu senden, zu empfangen und zu interpretieren

Conclusio: eine bereits fertig gerenderte WordPress Seite wird sehr viel schneller ausgeliefert, da sehr viel weniger Ressourcen benötigt werden.

Wie bei jedem anderen Cache auch gilt: Nur ein vorgewärmter Cache ist ein guter Cache!

2. Auto-Nginx Konfiguration

Das zweite „nette“ Feature des W3TotalCache-Plugins ist die automatische Erzeugung einer „nginx.conf“ Datei.
Diese wird vom Cache-Plugin dann ins Document-Root geschrieben, wenn man das Plugin einmal kurz deaktiviert und wieder aktiviert; unter der Voraussetzung, dass die WordPress-Installation hinter einem Nginx mit PHP-FPM läuft.
Dort legt das W3TotalCache-Plugin, je nach Konfiguration, passende Nginx-Regeln ab.

Diese „nginx.conf“ kann ganz einfach mit der folgenden Direktive in die Nginx-Vhost-Konfiguration eingebaut werden:

 include /pfad/zur/WordPress/Installation/nginx.conf

Testen ob die Konfiguration korrekt ist, und danach die neue Nginx-Konfiguration laden:

nginx -t && service nginx reload

Fini ! :)

Ergänzende Informationen

Am Rande sei erwähnt, dass ich den Browser-Cache in der W3TotalCache-Konfiguration abgeschaltet habe.
Das kann der Nginx in einer „nativen Form“ in der Vhost-Konfiguration auch:

        # Browser Caching
        location ~* \.(?:ico|css|js|jpe?g|png|gif|svg|pdf|mov|mp4|mp3|woff)$ {
                expires 365d;
                add_header Pragma public;
                add_header Cache-Control "public";
                gzip_vary on;
        }
2 Kommentare
  1. Matthias Radscheit
    Matthias Radscheit says:

    Danke für den Artikel. Ich bekomme im Zuge des NGINX Tests die Meldung, dass ${cache_uri} nicht bekannt ist. Wurde die Variable umbenannt?

    Schöne Grüße

    Antworten
    • Martin Wolfert
      Martin Wolfert says:

      Hallo Matthias,
      ich muss gestehen, dass ich nicht weiß, ob diese Variable in dem von mir beschriebenen Zusammenhang so noch funktional ist. Mein Post ist inzwischen ja ein wenig angestaubt.
      Ich arbeite aktuell mit Nginx 1.11.3 und habe aktuell eine völlig andere Konfiguration.

      Viele Grüße,
      Martin

Was denkst du darüber?

Want to join the discussion?
Feel free to contribute!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.