Die letzten Wochen hatte ich mit massiven Problemen meiner WordPress-Webseite zu kämpfen, so dass ich mich kurzerhand dazu entschloss, den bisher unter Plesk Onyx laufenden Server komplett neu aufzusetzen.
Herausgekommen ist dabei ein Nginx-only Setup mit Redis als Cache-Engine, Letsencrypt-Zertifikat für alle Domain-Aliases und einer Subdomain sowie CDN mit SSL-Unterstützung. Nebenher habe ich mein Setup entrümpelt und mich von einigen liebgewonnenen Elementen wie dem WP-Rocket-Plugin sowie (vorerst auch) Cloudflare verabschiedet.
Wenngleich ich erwähnen muss, dass sich Plesk grundsätzlich als komfortable Option zur Webserver-Administration anbietet, habe ich mich an vielen Einschränkungen gestört, wenn es darum geht bestimmte Parameter an die eigenen Bedürfnisse und Anforderungen anzupassen.
Vorher
- Ubuntu 16.04
- Plesk Onyx 17.5.3
- nginx 1.10
- php-fpm 7.1
- Letsencrypt
- WP-Rocket Plugin
- Disqus
- Cloudflare
Ladezeiten (Pingdom Stockholm, ohne Werbeskripte): 1,2 Sekunden, 1.5 MB
Aktuell
- Ubuntu 16.04
- EasyEngine
- nginx/1.13.7
- php-fpm 7.0
- Letsencrypt (angepasst)
- Redis-Server
- optional: Simple Cache/ Powered Cache
- (Key)CDN
Ladezeiten (Pingdom Stockholm, ohne Werbeskripte): 0,7 Sekunden, 865 kB
Schritt 1: EasyEngine einrichten und aktuelle Nginx-Version kompilieren
Easy Engine bietet gerade für Neulinge und nicht geübte WordPress-Betreiber eine effektive Möglichkeit in die NGINX-Welt hinein zu schnuppern. Auch wenn es in den letzten Monaten keine Updates gab, ist es für mich noch immer eine der besten Arten einen WordPress Nginx Server 2017 einzurichten. Version 4 ist aber in der Mache. Auf eine aktuelle Nginx-Version müsst ihr dennoch nicht verzichten.
Apache2 abschalten
Zunächst einmal schalten wir Apache2 ab und entfernen das Startup-Script, damit es nicht bei jedem Neustart des Servers automatisch mitläuft. Meldet euch per SSH-Login an euren Server an. Gibt die folgenden Befehle in den Terminal:
service apache2 stop update-rc.d -f apache2 remove
Falls ihr bereits jetzt Apache2 komplett von eurem System verbannen möchtet, schickt ihr diesen Befehl hinterher:
sudo apt-get remove apache2
Easy Engine installieren und anpassen
Gebt im Terminal
wget -qO ee rt.cx/ee && sudo bash ee
Easy Engine liefert auch einige wichtige weitere Komponenten mit, die die Administration eures Servers erleichteren. Diese Apps könnt ihr optional mit installieren – ich empfehle es jedenfalls. Der Befehl hierfür lautet:
ee stack install --all
Später könnt ihr unter der Adresse auf die Admin-Tools zurückgreifen:
http(s)://eurewebseite.de:22222
Bei der Installation zeigt euch Easy Engine im Terminal die benötigten Login-Daten an. Habt ihr diese verlegt, gebt ihr später folgenden Befehl ein, um einen gesicherten Zugang zu erhalten:
ee secure --auth nutzername
Im nächsten Schritt fragt Easy Engine nach einem Passwort – ansonsten wird ein zufällig generiertes vergeben.
Easy Engine Konfigurationsdatei anpassen
Bevor ihr euch an die Installation der Wordpress-Seite macht, würde ich euch empfehlen, händisch noch einige Änderungen an der Easy Engine-Konfigurationsdatei vorzunehmen. Diese befindet sich unter etc/ee/ee.conf
.
WordPress-Webseite per Befehl installieren
Prima, jetzt kann es losgehen. Wir erstellen eine Wordpress-Seite samt Datenbanken und FastCGI-Cache. Die entsprechende Konfiguration von NGINX wird automatisch durchgeführt.
Wir installieren WordPress, PHP 7.0, Redis und Letsencrypt für ein kostenloses SSL-Zertifikat.
ee site create eurewebseite.de --wpredis --php7 --letsencrypt
Am Ende zeigt euch Easy Engine die Zugangsdaten nochmal an und ihr könnt euch im WordPress-Backend anmelden. Hier müsst ihr noch die WordPress-Sprache auf Deutsch umstellen – das bekommt ihr aber hin.
Standardmäßig installiert werden zwei Caching-Plugins, Nginx-helper und WP-Redis. Diese schalten wir später ab bzw. passen sie, so dass unsere Cache-Dateien auch unter http/2 und SSL gelöscht werden.
Option Redis-Server installieren (oder aktuelle Version selbst kompilieren)
apt-get install build-essential apt-get install tcl wget
Redis 4 kompilieren
wget https://download.redis.io/redis-stable.tar.gz tar xvzf redis-stable.tar.gz cd redis-stable/ make distclean make make test make install
Redis-Server installieren
cd utils/ ./install_server.sh
Ihr könnt die vorgeschlagenen Default-Werte übernehmen oder eigene Einstellungen definieren. Für eine vollständige Kompatibilität mit EasyEngine muss der Dienst redis-server lauten. Am Ende werden euch die gewählten Optionen im Überblick zusammengefasst.
Die nächsten beiden Kommandozeileneingaben sind optional.
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf && sysctl -p echo never > /sys/kernel/mm/transparent_hugepage/enabled
Soweit ist nun der Redis-Server eingerichtet. Ihr müsst ihn nur noch starten und testen.
systemctl start redis_6379 systemctl status redis_6379
bzw.
systemctl start redis systemctl status redis
Schritt 2: Nginx aktualisieren und Konfiguration anpassen
Die installierte und ein wenig veraltete Version von nginx ersetzen wir durch eine frisch kompilierte Variante mit (optionalem) Pagespeed-Modul.
Hierfür geben wir folgenden Befehl ein:
bash < (wget -O - https://raw.githubusercontent.com/VirtuBox/nginx-ee/master/nginx-build.sh)
oder um nginx mit Pagespeed-Modul zu verwenden:
bash < (wget -O - https://raw.githubusercontent.com/VirtuBox/nginx-ee/master/nginx-build-pagespeed.sh)
Die passende nginx.conf hohlen wir uns auch automatisch:
wget -O /etc/nginx/nginx.conf https://raw.githubusercontent.com/VirtuBox/nginx-ee/master/etc/nginx/nginx.conf nginx -t service nginx restart
Optional: Web-Support
wget -O /etc/nginx/conf.d/webp.conf https://raw.githubusercontent.com/VirtuBox/nginx-ee/master/etc/nginx/conf.d/webp.conf
Danach müsst ihr aber eine Konfigurationsdatei namens wepb-enabled.conf unter /var/www/euredomain.tld/conf/nginx erstellen:
Schritt 3: Letsencrypt mit Domain Alias
Stellt euch vor, eurer Blog ist über zwei Domains erreichbar: etwa über über eine .DE- als auch .COM-Endung. Wenn das der Fall ist, stellt Letsencrypt in dieser Konfiguration leider nur ein Zertifikat für die Hauptdomain aus. Gibt ein Nutzer instinktiv noch eure alte Domain als, wird die Anfrage nicht verschlüsselt weitergeleitet.
Ein weiteres Problem: eure Subdomains, etwa für den Einsatz als ZoneAlias bei KeyCDN, werden so ebenfalls nicht verschlüsselt.
Die Lösung, die ich für mich gefunden habe, ohne Einsatz von Plugins, mag vielleicht nicht besonders elegant sein, scheint aber ganz gut zu funktionieren:
Wechselt in das Letsencrypt-Verzeichnis:
cd /opt/letsencrypt/
Ändert und erweitert den folgenden Befehl entsprechend euren Wünschen ab. Ihr müsst den Pfad zu eurer Domain sowie (logischerweise) die Domainnamen ändern. Ihr könnt auch weitere hinzufügen.
Im Anschluss werden ihr gefragt, ob ihr das bestehende Zertifikat erneuern und erweitern wollt. Bestätigt die Frage mit “E” (Expand). Das könnte dann in etwa so aussehen:
Do you want to expand and replace this existing certificate with the new certificate? ------------------------------------------------------------------------------- (E)xpand/(C)ancel: E Renewing an existing certificate Performing the following challenges: http-01 challenge for domain.tld http-01 challenge for domain2.tld http-01 challenge for www.domain.tld http-01 challenge for www.domain2.tld http-01 challenge for cdn.domain.tld Using the webroot path /var/www/domain.tld/htdocs for all unmatched domains. Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/domain.tld/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/domain.tld/privkey.pem Your cert will expire on 2018-03-15. To obtain a new or tweaked version of this certificate in the future, simply run letsencrypt-auto again. To non-interactively renew *all* of your certificates, run "letsencrypt-auto renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le root@v81553:/opt/letsencrypt#
Schritt 4: WordPress (Plugins) anpassen
Soweit ist eurer Server bereits prima eingerichtet und ihr könntet im Grunde bereits so ans Werk gehen. Das Problem: das installierte Nginx Helper-Plugin hat immer wieder Probleme euren Cache zu leeren.
Nginx Helper Plugin
Als Lösung bietet es sich an, in der wp-config.php-Datei einen angepassten Speicherort für den Cache anzugeben:
define( 'RT_WP_NGINX_HELPER_CACHE_PATH','/var/www/euredomain.tld/htdocs/wp-content/cache/nginx-cache');
Simple Cache
Schaltet das Nginx Helper Plugin sowie Redis Object Cache ab. Installiert stattdessen Simple Cache. Wechselt über Einstellungen->Simple Cache in das Konfigurationsmenü. Wichtig: schaltet den Modus für fortgeschrittene Anwender ein (rechts oben: “Enable Advanced Mode: Yes”), da ihr sonst Redis nicht als Object Cache verwenden könnt. Scrollt nun etwas runter und wählt unter Object Cache (Redis or Memcache)/ In Memory Cache: Redis aus.
Page Cache habe ich i.Ü. aktuell nicht aktiviert, da es in meinem Fall keine Ladezeitenverbesserungen mit sich brachte. Die Option “Enable gzip compression” könnt ihr auf “no” belassen. In unserem Fall ist die Kompression serverseitig bereits aktiviert.
Wie ihr seht, macht Simple Cache seinem Namen alle Ehren und erschlägt euch nicht mit zig Einstellungen sondern bleibt übersichtlich, elegant und effektiv. Verglichen mit anderen beliebten Cache Plugins wie WP Total Cache, WP Rocket oder WP Super Cache habe ich zwar weniger Einstellungen und Möglichkeiten, am Ende des Tages aber nur selten echte Nachteile.
WP Rocket möchte ich da besonders erwähnen, da mir das Plugin in den letzten Jahren treu zur Seite stand und der Support auch immer mit kompetentem Rat zur Seite steht. Allerdings bin ich immer weniger von seiner eigentlichen Aufgabe überzeugt: das Caching führt immer wieder zu Problemen. CSS-Dateien und JS-Skripte etwa werden mit unserem Setup nicht komprimiert. Ebenso fehlt uns eine Option zum Preloading oder die Kompatibilität mit einem CDN-Dienst wie Cloudflare oder KeyCDN.
Kleines Zwischenfazit WordPress Nginx Server 2017
Auch ohne diese Einstellungen ist der Server recht flott unterwegs, wohlgemerkt ohne auf den Einsatz eines Premium-Themes und benötigten Plugins zu verzichten. Oftmals werden solche Tutorials mit einer komplett leeren WordPress-Installation und einem Standard-Theme durchgeführt. Die Aussagekraft solcher “speed tutorials” dürfte sich dementsprechend in Genzen halten. Beliebt ist es etwa, die eigene Webseite unter Pingdom so schnell hintereinander anzupingen, so dass eine möglichst schnelle (und gecache?) Ladezeit angezeigt wird. Was mit einem alltäglichen Nutzerverhalten recht wenig zu tun haben dürfte. Im Screenshot seht ihr die Ladezeiten beim ersten Aufruf mit meinem aktuellen Theme sowie allen benötigten Plugins.
Das ist für mich ein ziemlich passabler Wert: immerhin habe ich mich nicht stundenlang durch verschachtelte Plugin-Einstellungen und Konfigurationen kämpfen müssen. Vielleicht geht es euch ja anders, wenn ihr dieser Anleitung folgt und sie als komplex und konfus empfindet. Ich hoffe nicht – lasst es mich wissen!
Spaßeshalber habe ich sämtliche Plugins abgeschaltet (außer eben Simple Cache) und erzielt mit dem Standard-Thema Twenty Seventeen folgendes Ergebnis:
Jetzt könnt ich natürlich hergehen und mich darüber freuen, dass sich die Ladezeiten halbiert haben, das neun Anfragen weniger gestellt wurden und das sich die Größe der Webseite um etwa ein Drittel verringert hätte. Kurzfristig gedacht ist das auch der Fall.
Außer acht gelassen wurden aber einige Aspekte: die Webseite sieht durch das Standard-Theme beliebig und austauschbar aus. Unter Einstellungen->Lesen wurde die Anzahl der angezeigten Artikel (4) auf der Startseite so reduziert, dass ein passabler Wert angezeigt wird. Hier könnte man also noch weiter schummeln, etwa wenn die Bilder bzw. Thumbnailgröße der Artikel einen größeren Geschwindigkeitsvorteil verhindern. Interaktive und individuelle Elemente wurden komplett von der Seite getilgt, die Kommentarfunktion, Shortcodes etc. komplett gelöscht. Und trotz all dieser Maßnahmen muss man das Vorgehen relativieren: sicherlich haben sich Ladezeiten absolut betrachtet beinahe halbiert, möglicherweise aber auch die Halbwertzeit des Blogs.
Letztlich geht es aber darum, die Balance zwischen Funktionalität und Effektivität zu finden. Daher machen wir uns lieber ans Feintuning der Webseite. Mit dem Powered Cache Plugin etwa können wir ein CDN leichter einbinden und unsere CSS- und JS-Dateien komprimieren. Das kann dann etwa sinnvoll sein, wenn eurer Theme oder eure Plugins relativ vieler dieser Dateien ausliefern.
Powered Cache Plugin & KeyCDN
Schaltet Simple Cache ab und installiert Powered Cache. Kleine Warnung vorweg: auch hier müsst ihr händisch die nginx-Konfiguration anpassen, ich habe aber alles für bereits vorbereitet.
Öffnet unter /etc/nginx/sites-available/ die Konfigurationsdatei des Servers und fügt include common/poweredcache.conf;
ein, wie hier zu sehen:
Testet, ob die Einstellungen korrekt sind:
nginx -t
Startet die Dienste (Nginx, PHP-FPM neu) und löscht die Cache-Dateien:
ee stack reload ee clean --all
Wechselt in eurem WordPress-Adminbereich in die Plugin-Einstellungen: Powered Cache->Settings. Aktiviert Reis als Object Cache und setzt einen Haken bei “SSL Cache”. Unter Advanced Options aktiviert ihr “Remove Query Strings from Static Objects” – das bringt euch einen kleinen Geschwindigkeitsschub. Optional: Im Reiter CDN aktiviert ihr “Enable CDN Support” und fügt euren Hostnamen ein.
Meine Einstellungen für KeyCDN sehen so aus. Eine detaillierte Anleitung findet für die diverse Plugins (WP Rocket, CDN-Enabler etc) ihr hier.
Soweit haben wir den Server noch ein klein wenig besser gemacht. Das sollte für diesen Sonntag reichen. Einige Dinge werde ich noch ergänzen, etwa eine bessere Anleitung für KeyCDN oder vernünftige Einstellungen für das Pagespeed-Modul bei nginx – das habe ich bislang ausgelassen.
To-Do-Liste
- ngx_pagespeed
- Key-CDN-Anleitung
- Bilder (per Skript) optimieren
- Nginx-Konfiguration erweitern