Springe zum Inhalt

WordPress: Nginx und HHVM

Durch Berichte über die erfolgreiche Umstellung von WordPress unter Apache und mod_php5 auf Nginx und HHVM von Sergej Müller war ich optimistisch, die dort genannten Geschwindigkeitsvorteile auch für mein Blog nutzbar zu machen.

Nginx war mir schon ein Begriff. Der alternative Webserver steht für Resourcenfreundlichkeit und Geschwindigkeit. Leider bieten viele PHP-Projekte nur Unterstützung für Apache, Beispiele für die Nginx-Konfiguration muss man sich oft mühsam selbst zusammensuchen. Nur durch Zufall stieß ich auf die Datei nginx.conf im Rootverzeichnis der WordPress-Installation, die offensichtlich durch das von mir eingesetzte Plugin W3-Total-Cache anlegt und bei Änderungen in der Konfiguration auch entsprechend angepasst wird. In dieser Datei fanden sich dann die für Nginx notwendigen Anweisungen, um korrekt mit dem Caching-Plugin zusammenarbeiten zu können.

Ein weiterer wichtiger Punkt war das Handling der Sitemap-Adressen. Ich setzte zur Erstellung der für Google und anderer Suchmaschinen vorteilhaften Sitemap das WordPress-Plugin Google XML Sitemaps ein. Erfreulicherweise erkennt das Plugin, dass es unter Nginx läuft und liefert auf der Pluginseite Hinweise zur Konfiguration des Webservers.

Eine Besonderheit des Blogs hier ist, dass alle Anfragen auf HTTPS umgeleitet werden, außerdem ist es auch per IPv6 erreichbar. Mit all den Einzelteilen sieht mein Konfigurationsschnipsel für das Blog dann folgendermaßen aus:

server {
        listen   80; ## listen for ipv4; this line is default and implied
        listen   [::]:80 default_server ipv6only=on; ## listen for ipv6
 
        server_name blog.tausys.de;
        return 301 https://$host$request_uri;
}
 
server {
        listen   443 ssl; ## listen for ipv4; this line is default and implied
        listen   [::]:443 default ipv6only=on ssl; ## listen for ipv6
 
        server_name blog.tausys.de;
        root /xxxxxxxxxx;
        index index.php index.html index.htm;
 
        include hhvm.conf;
 
        ssl on;
        ssl_certificate /xxxxxxxxxx/crt.pem;
        ssl_certificate_key /xxxxxxxxxx/key.pem;
 
        location / {
                try_files $uri $uri/ /index.php?$args;
        }
 
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
                deny all;
        }
 
        location ~* \.(js,css,png,jpg,jpeg,gif,ico,woff,ttf,svg,otf)$ {
                expires 30d;
                add_header Pragma public;
                add_header Cache-Control "public";
        }
 
        location = /robots.txt {
                rewrite ^ /index.php;
        }
 
        rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml$ "/index.php?xml_sitemap=params=$2" last;
        rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;
        rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;
        rewrite ^/sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;
 
        include /xxxxxxxxxx/nginx.conf;
}

Die Zeile 49 enthält das Include der durch W3-Total-Cache erstellten Konfigurationsdatei.

In Zeile 17 wird die allgemeine Konfiguration von HHVM einbezogen. Mit HHVM konnte ich erst einmal nichts anfangen, Wikipedia liefert aber auch hier entspechende Aufschlüsse. Die Installation war relativ einfach, da für einige Distributionen bereits vorcompilierte Pakete bereitgestellt werden, die mit Hilfe der Kurzanleitungen anschließend durch die lokalen Paketverwaltung installiert werden können.

Vor dem Start von Nginx muss dann unbedingt der evtl. noch vorhandene Apache beendet oder für andere Ports als 80 bzw. 443 konfiguriert werden.

Gesagt, getan. Das Blog lief sofort und so weit ich sehen konnte, liefen auch alle Plugins korrekt. Getestet werden sollte auf alle Fälle, ob der Zugriff auf robots.txt und, falls vorhanden, die sitemap.xml funktioniert. Die Antwortzeiten sind einfach phantastisch!

Da ich hier noch viele andere vHost betreibe, die verschiedene PHP-Pakete beinhalten, machte ich mich nun an die Umstellung der restlichen virtuellen Hosts. Leider musste ich dabei feststellen, dass HHVM etwas pingelig mit evtl. nicht ganz regelkonform programmierten Anwendungen ist. So z.B. ist es mir nicht gelungen, Friendica unter HHVM zum Laufen zu bewegen. Genau für diesen Fall bietet es sich an, den bereits vorhandenen Apache auf der lokalen Adresse auf einem anderen Port lauschen zu lassen. Die Anfragen von außen an Friendica können von Nginx per proxy_pass-Anweisung dann an Apache weiterleitet werden. Die Nginx-Proxy-Konfiguration für Friendica könnte dann ungefähr so aussehen:

server {
        listen   80; ## listen for ipv4; this line is default and implied
        listen   [::]:80; ## listen for ipv6
 
        server_name friends.tausys.de;
        return 301 https://$host$request_uri;
}
 
server {
        listen   443 ssl; ## listen for ipv4; this line is default and implied
        listen   [::]:443 ssl; ## listen for ipv6
 
        server_name friends.tausys.de;
 
        ssl on;
        ssl_certificate /xxxxxxxxxx/crt.pem;
        ssl_certificate_key /xxxxxxxxxx/key.pem;
 
        location / {
                proxy_pass http://localhost:999999;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
        }
}

Auch hier gibt es bei mir wieder die Besonderheit, dass alle Anfragen an den unverschlüsselten HTTP-Port 80 zuerst einmal auf verschlüsseltes HTTPS umgeleitet werden. Anschließend werden die Anfragen an den nur lokal lauschenden Apache weitergeleitet.

Andere Pakete, für die zur Zeit keine entsprechende Nginx-Module zur Verfügung stehen, unter anderem WebDAV  und SVN, musste ich ebenfalls zur Weiterleitung an Apache per Nginx-Proxy konfigurieren.

Nach ca. einer Woche Laufzeit von Nginx und HHVM musste ich leider feststellen, dass sich HHVM auch mal mitten im Betrieb verabschieden kann. Im Logfile findet sich dann nur ein Core dumped und unter /tmp/ ist ein Stacktrace zu finden. Leider scheint lt. Stacktrace die Situation nicht einfach nachstellbar zu sein, um einen entsprechenden Bugreport für HHVM erstellen zu können. Ich habe mich deshalb dafür entschieden, monit einzusetzen, welches Services überwachen und im Fehlerfall automatisch neu starten kann. Die entsprechende Konfigurationsdatei für HHVM sieht dann bei mir so aus:

 check process hhvm with pidfile /var/run/hhvm/pid
   group system
   group hhvm
   start program = "/etc/init.d/hhvm start" with timeout 60 seconds
   stop program  = "/etc/init.d/hhvm stop"
   if failed host blog.tausys.de port 443 type tcpssl protocol http then restart
   if 3 restarts within 5 cycles then timeout
   depend on hhvm_bin
 
 check file hhvm_bin with path /usr/bin/hhvm
   group hhvm
   include /etc/monit/templates/rootbin

Ich hoffe, Euch mit meiner Beschreibung ein bisschen weitergeholfen zu haben und würde mich über Berichte zu Erfolgen oder Misserfolgen in den Kommentaren freuen.

4 Gedanken zu „WordPress: Nginx und HHVM

    1. shogun

      Hallo Hans-Joachim,

      ich habe dazu einen eigenen Rootserver gemietet, auf dem neben WordPress auch noch viele andere Sachen laufen. So habe ich freie Hand über die Konfiguration.

      Gruß
      Jens

  1. Schroeffu

    Sehr guter, ausführlicher Artikel, gefällt mir :- )! Läuft HHVM inzwischen stabiler? Hat es sich mehr etabliert neben mod-fpm? Ich habe mehrfach gelesen die Kompatibilität ist nicht immer gewährleistet, also nicht jede PHP Applikation läuft darunter (wie dein Friedica)

    Ach, ich werde es einfach mal ausprobieren :) Zur Not geht ja auch HHVM und Mod-FPM im Parallelbetrieb.

    1. Jens Tautenhahn

      HHVM läuft hier mittlerweile sehr stabil. Seit mehreren Wochen hatte ich keinen Crash mehr. Auch habe ich im Falle eines Crash vorgesorgt, indem ich ein systemd Unitfile erstellt habe, welches HHVM im Fall der Fälle automatisch wieder startet.

      Friendica wie auch Piwik laufen seit längerem hervorragend unter HHVM. Seit zwei Tagen (mit einer klitzekleinen Anpassung in HHVM) sogar Wallabag, welches das Symfony-Framework verwendet.

      Viel Erfolg beim Ausprobieren!

Kommentare sind geschlossen.