How To

WordPress und Redis im Docker-Container betreiben

Beim betrachten der Seite Website-Zustand des Blogs, fiel mir auf, dass WordPress meint, durch Hinzufügen eines Object-Caches wird alles viel besser, schneller und es regnet Einhörner.

Einhörner regnen ist cool, also habe ich mich mal dran gemacht WordPress Redis miteinander zu verheiraten. Alles natürlich im Docker-Container.

Gesagt getan, hier ein Guide dazu!

Docker-Konfiguration

Meine bisherige Docker-Compose Konfiguration sah so aus. Es liegt hier nahe, Redis im gleichen Docker-Netz zu betreiben wie den MySQL- und WordPress-Container.

				
					version: '3.8'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: sqlPassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
  wordpress:
    image: wordpress:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./wp-content:/var/www/html/wp-content
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_CONFIG_EXTRA: |
        define('FORCE_SSL_ADMIN', true);
        define('FORCE_SSL_LOGIN', true);
        define('WP_HOME','https://blog.gretzki.ddns.net/');
        define('WP_SITEURL','https://blog.gretzki.ddns.net/');
volumes:
  db_data:
				
			

Eigentlich Standard, die WordPress-Environment-Variablen brauche ich, weil WordPress hinter einem HA-Proxy rennt (wegen der FQDN) und alles über Letsencrypt-Zertifikat SSL-verschlüsselt ausgeliefert wird.

Neue Docker-Konfiguration

Als nächstes fügen wir hier eine Redis-Instanz zu. Diese steht dann, nach einem Neustart der Instanzen zur Verfügung.

				
					version: '3.8'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: sqlPassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    redis:
      image: redis:latest
    ports:
      - 6379:6379
    wordpress:
    image: wordpress:latest
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./wp-content:/var/www/html/wp-content
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_CONFIG_EXTRA: |
        define('FORCE_SSL_ADMIN', true);
        define('FORCE_SSL_LOGIN', true);
        define('WP_HOME','https://blog.gretzki.ddns.net/');
        define('WP_SITEURL','https://blog.gretzki.ddns.net/');
volumes:
  db_data:
				
			

Nach einem Neustart mit docker compose sollten 3 Instanzen hochfahren.

Ein Blick mit docker ps -a verrät, ob die Container hochgefahren und gestartet sind.

Der Name des gestarteten Redis-Containers müssen wir uns merken, der ist für die spätere Konfiguration wichtig. In meinem Fall mywordpressblog-redis-1.

WordPress-Einstellungen und Plugins

WordPress-Plugins

Ich verwende als WordPress-Plugin das, in den Empfehlungen genannte, Redis Object Cache. Zum Zeitpunkt der Erstellung dieses Blogbeitrags, findet man das Plugin hier:

Redis Object Cache

 

Alternativ, installiert man das Plugin wie gehabt über die Plugin-Oberfläche seiner WordPress-Instanz.

Nach der Installation, steht das neue Plugin unter WordPress-Dashboard –> Einstellungen –> Redis.

Und funktioniert nicht! Schade.

Redis Cache-Plugin, direkt nach der Installation

Ein Blick auf Diagnose, lässt vermuten, dass wir noch nicht ganz fertig sind.

Redis Object Cache Diagnose, direkt nach der Installation

Installation des Drop-In Predis

Wahrscheinlich gibt es viel einfachere Möglichkeiten, ich zeige im Folgenden die Installation und Konfiguration des Drop-In „Predis“.

Dieses Drop-In muss in den laufenden Docker-Container installiert werden. Hierfür verbinden wir uns in den gestarteten WordPress-Docker-Container.

Mit docker ps -a wissen wir den Namen des laufenden Docker-Containers mywordpressblog-wordpress-1.

Mittels docker exec -ti mywordpressblog-wordpress-1 bash verbinden wir uns in den laufenden Container.

Um jetzt Predis zu installieren, verwenden wir den Befehl pecl. Pecl ist die Abkürzung von PHP Extension Community Library.

https://pecl.php.net/

Mit pecl install predis wird Predis in den Container installiert. Der Befehl hierfür lautet

pecl install redis 

Die folgenden Zeilen zeigen den Beginn der Installation. Die Abfragen habe ich alle mit n beantwortet, bzw. default gelassen.

				
					root@3af39d97789b:/var/www/html# pecl install redis
downloading redis-5.3.7.tgz ...
Starting to download redis-5.3.7.tgz (275,200 bytes)
.........................................................done: 275,200 bytes
31 source files, building
running: phpize
Configuring for:
PHP Api Version: 20200930
Zend Module Api No: 20200930
Zend Extension Api No: 420200930
enable igbinary serializer support? [no] :
enable lzf compression support? [no] :
enable zstd compression support? [no] :
building in /tmp/pear/temp/pear-build-defaultuser1rpQV1/redis-5.3.7
running: /tmp/pear/temp/redis/configure --with-php-config=/usr/local/bin/php-config --enable-redis-igbinary=no --enable-redis-lzf=no --enable-redis-zstd=no
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for cc... cc
.
.
.

Build complete.
Don't forget to run 'make test'.

running: make INSTALL_ROOT="/tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7" install
Installing shared extensions: /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local/lib/php/extensions/no-debug-non-zts-20200930/
running: find "/tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7" | xargs ls -dils
1209041 4 drwxr-xr-x 3 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7
1209082 4 drwxr-xr-x 3 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr
1209083 4 drwxr-xr-x 3 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local
1209084 4 drwxr-xr-x 3 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local/lib
1209085 4 drwxr-xr-x 3 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local/lib/php
1209086 4 drwxr-xr-x 3 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local/lib/php/extensions
1209087 4 drwxr-xr-x 2 root root 4096 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local/lib/php/extensions/no-debug-non-zts-20200930
1209081 3540 -rwxr-xr-x 1 root root 3622176 Jan 8 17:05 /tmp/pear/temp/pear-build-defaultuser1rpQV1/install-redis-5.3.7/usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so

Build process completed successfully
Installing '/usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so'
install ok: channel://pecl.php.net/redis-5.3.7
configuration option "php_ini" is not set to php.ini location
You should add "extension=redis.so" to php.ini
				
			

Irgendwann am Ende sollte eine Meldung stehen dass die Installation erfolgreich war.

Jetzt verlassen wir den Container mit exit und starten den Container mit docker stop mywordpressblog-wordpress-1 und docker start mywordpressblog-wordpress-1 neu. Docker-Compose stoppen und starten funktioniert nicht (für dieses Beispiel), da ein neuer WordPress-Container angelegt werden wird und alle Einstellungen verloren gehen.

Ein Blick auf die Diagnose Seite des Redis Cache Plugins sollte irgendwie sowas anzeigen.

Na gut, funktioniert immer noch nicht. Aktuell versucht WordPress die Verbindung zu Redis mittels localhost (127.0.0.1) herzustellen. Was nicht funktioniert, da localhost der WordPress-Container ist.

Also, müssen wir WordPress mitteilen wo es die Redis Instanz erreichen kann.

Verbindung zwischen WordPress und Redis herstellen

Auf der Installations-Seite vom Redis-Object-Cache finden wir folgenden Eintrag.

https://wordpress.org/plugins/redis-cache/#other_notes

CONNECTION PARAMETERS

By default the object cache drop-in will connect to Redis over TCP at 127.0.0.1:6379 and select database 0.

To adjust the connection parameters, client, timeouts and intervals, please see the connection parameters wiki page.

OK, dann auf zur Connection Parameter Wiki Page.

Hier finden wir dann alles um die Verbindung zwischen WordPress und Redis herzustellen.

https://github.com/rhubarbgroup/redis-cache/wiki/Connection-Parameters

Die folgenden Parameter müssen wir jetzt in die wp-config.php Datei einfügen.

 

				
					define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );
// change the database for each site to avoid cache collisions
define( 'WP_REDIS_DATABASE', 0 );
// supported clients: `phpredis`, `credis`, `predis` and `hhvm`
define( 'WP_REDIS_CLIENT', 'predis' );
// bypass the object cache, useful for debugging
define( 'WP_REDIS_DISABLED', false );
				
			

Die Frage ist nur, wie bekommen wir die Einträge in die wp-config.php?

Es gibt, wie immer, mehrere Möglichkeiten. 

  1. Über volume Parameter wird beim Start von WordPress die Datei wp-config.php vom Host in den Container gebracht
  2. Mittels docker cp ... kann man im laufenden Container die Datei vom Container zum Host kopieren, editieren und mittels docker cp wieder zurückkopieren
  3. Als Environment-Variable, wie bereits die anderen WordPress-Parameter in der docker-compose.yaml. 

 

Achtung bei Option 2! Wenn man die Container entfernt und dann neu startet, sind die Einträge in der Datei nicht mehr vorhanden. Sollte es also etwas persistenter sein, muss der Weg über Volumes gegangen werden!

Wir erweitern also die docker-compose.yaml um die folgenden Parameter.

 

				
					version: '3.8'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    redis:
      image: redis:latest
      ports:
        - 6379:6379
    wordpress:
      image: wordpress:latest
      ports:
        - 80:80
        - 443:443
      restart: always
      volumes:
        - ./wp-content:/var/www/html/wp-content
      environment:
        WORDPRESS_DB_HOST: db:3306
        WORDPRESS_DB_USER: wordpress
        WORDPRESS_DB_PASSWORD:wordpress
        WORDPRESS_CONFIG_EXTRA: |
          define('FORCE_SSL_ADMIN', true);
          define('FORCE_SSL_LOGIN', true);
          define('WP_HOME','https://blog.gretzki.ddns.net/');
          define('WP_SITEURL','https://blog.gretzki.ddns.net/');
          define('WP_REDIS_HOST', 'mywordpressblog-redis-1');
          define('WP_REDIS_PORT', 6379);
          define('WP_REDIS_TIMEOUT', 1);
          define('WP_REDIS_READ_TIMEOUT', 1);
          define('WP_REDIS_DATABASE', 0);
          define('WP_REDIS_CLIENT', 'predis');
          define('WP_REDIS_DISABLED', false);
volumes:
  db_data:
				
			

Startet man jetzt den WordPress-Container neu und sieht sich die Übersichts-Seite von Redis Object Cache an, sollte man folgendes Bild sehen.

Damit sollte WordPress ordnungsgemäß mit Redis als Object-Cache arbeiten.

Viel Vergnügen beim nachbauen!