BetriebLink zu diesem Abschnitt
Zuletzt geändert am
Container und DateienLink zu diesem Abschnitt
/var/www/html ist ein benanntes Docker-Volume mit den Dateien aus dem Image. Aus dem Projektverzeichnis eingehängt sind nur wp-content/, wp-config.php und die Datei mit den Zugangsdaten.
Einzeldatei-Mounts und Inodes
Ein Bind-Mount einer einzelnen Datei hängt an deren Inode. Wer die Datei auf dem Host per mv, sed -i oder mit einem Editor ändert, der eine neue Datei schreibt und umbenennt, bekommt eine neue Inode. Der Container sieht dann weiter den alten Stand, der Host den neuen. md5sum auf beiden Seiten zeigt den Unterschied. Solche Dateien immer an Ort und Stelle überschreiben. Ein docker restart hängt den Mount wieder an die aktuelle Datei.
- Neue Dateien im Projektverzeichnis erreichen den Container nicht von allein. Sie brauchen einen eigenen Eintrag unter
volumes:und einen neuen Container. - Eine Datei, die als Einzeldatei gemountet wird, muss vor dem Start existieren. Sonst legt Docker an ihrer Stelle ein Verzeichnis an.
- WP-CLI gehört ins Image, nicht nachträglich in den laufenden Container. Sonst ist es nach jedem
docker compose up -dwieder weg. - Elasticsearch läuft im Container unter UID 1000. Gehört das Datenverzeichnis jemand anderem, landet der Container in einer Neustartschleife mit
AccessDeniedException. Abhilfe:chown -R 1000:1000 esdata.
Zugangsdaten außerhalb der VersionskontrolleLink zu diesem Abschnitt
wp-config.php ist versioniert, sie enthält die ganze Konfiguration der Instanz. Geheimnisse wie das SMTP-Passwort stehen deshalb in einer eigenen Datei, die wp-config.php einbindet:
if ( file_exists( __DIR__ . '/wp-config-secrets.php' ) ) {
require_once __DIR__ . '/wp-config-secrets.php';
}
wp-config-secrets.php steht in .gitignore, versioniert ist nur eine Vorlage wp-config-secrets.sample.php. Fehlt die Datei, läuft der Shop trotzdem, nur der Mailversand nicht.
Warum nicht verschlüsseln? SMTP meldet sich per AUTH LOGIN mit dem Passwort im Klartext an. Ein Geheimnis, das sich zurückrechnen lässt, ist also unvermeidbar. Wählen kann man nur den Ort:
| in der Datenbank (Plugin-Standard) | als PHP-Konstante | |
|---|---|---|
| in jedem Datenbank-Dump | ja | nein |
| im Backend sichtbar und änderbar | ja | nein |
| per SQL-Injection erreichbar | ja | nein |
WP Mail SMTP empfiehlt aus demselben Grund die Konstanten (WPMS_SMTP_USER, WPMS_SMTP_PASS).
WP-Cron und automatische UpdatesLink zu diesem Abschnitt
Pakete aus dem Konfigurations-Assistenten setzen DISABLE_WP_CRON nicht, dort läuft WP-Cron weiter über Seitenaufrufe. Ob sie automatisch aktualisieren, hängt an der Karte „Automatisch aktualisieren“ im Assistenten, siehe Erweiterungen. Einen System-Cron braucht erst, wer DISABLE_WP_CRON selbst setzt.
Ist in wp-config.php DISABLE_WP_CRON gesetzt, löst WordPress geplante Aufgaben nicht mehr über Seitenaufrufe aus. Ohne Ersatz laufen dann weder automatische Updates noch der Action Scheduler von WooCommerce, und damit auch keine Webhooks. Ersatz ist ein System-Cron auf dem Host:
#!/bin/bash
# /usr/local/bin/woocommerce-wp-cron.sh, per crontab alle fünf Minuten
set -u
CONTAINER=woocommerce-web-1
docker inspect -f '{{.State.Running}}' "$CONTAINER" 2>/dev/null | grep -q true || exit 0
docker exec "$CONTAINER" wp cron event run --due-now --allow-root \
>> /var/log/woocommerce-wp-cron.log 2>&1
*/5 * * * * /usr/local/bin/woocommerce-wp-cron.sh
Die Prüfung auf den laufenden Container hält das Log sauber, solange der Stack gestoppt ist.
Der Schalter im Backend reicht nicht. Automatische Updates brauchen das Ereignis wp_maybe_auto_update. Es entsteht normalerweise bei der Installation, kann aber fehlen. Prüfen und gegebenenfalls einplanen:
wp cron event list | grep wp_maybe_auto_update \
|| wp cron event schedule wp_maybe_auto_update now twicedaily
Reihenfolge. Der Updater installiert nur, was die Prüfungen vorher gefunden haben (wp_version_check, wp_update_plugins, wp_update_themes). Läuft er davor, tut er nichts. Der Standardabstand stellt das her, nach einem manuellen now korrigiert es sich mit dem nächsten Durchlauf.
Den Updater nie außerhalb von Cron aufrufen
WordPress deaktiviert ein Plugin vor dem Update und verlässt sich darauf, dass es danach wieder aktiviert wird. Diesen Schritt überspringt es nur, wenn wp_doing_cron() wahr ist. Ein Aufruf per wp eval-file lässt alle aktualisierten Plugins deaktiviert zurück. Für einen manuellen Lauf immer:
wp cron event run wp_maybe_auto_update
WooCommerce und Hauptversionen. WooCommerce blockiert automatische Updates über eine Hauptversion hinweg selbst (wc_prevent_dangerous_auto_updates()). Das ist gewollt: Solche Sprünge brauchen eine Datenbankmigration zu einem kontrollierten Zeitpunkt. Nach einem Update:
wp wc update
wp eval 'echo get_option("woocommerce_db_version") . " / " . WC()->version;'
Meldet WP-CLI „'wc' is not a registered wp command", ist WooCommerce deaktiviert.
Erweiterungen ohne Update-QuelleLink zu diesem Abschnitt
WordPress aktualisiert nur, was aus dem WordPress-Verzeichnis kommt. Eine Erweiterung, die aus einer ZIP-Datei oder von einer URL installiert wurde, meldet nie eine neue Fassung, auch nicht mit eingeschalteten automatischen Updates. Im WooCommerce-Stack betrifft das EU-Captcha und den Gewährleistungshinweis (ospo-gewaehrleistung). Eine neue Fassung spielt man im Backend unter Plugins → Neues Plugin hinzufügen → Plugin hochladen ein, oder per WP-CLI mit --force, das die vorhandene Fassung ersetzt:
wp plugin install https://raw.githubusercontent.com/Myra-Security-GmbH/eu-captcha-wordpress/main/eu-captcha.zip --force
MailversandLink zu diesem Abschnitt
Das Image wordpress:php8.4-apache enthält keinen Mailserver, /usr/sbin/sendmail fehlt. Ohne SMTP-Relay scheitern Bestellbestätigungen und Kontaktformulare still. Der Versand läuft deshalb über WP Mail SMTP an einen SMTP-Dienst, die Zugangsdaten als Konstanten (siehe oben).
Wenn die Anmeldung beim Relay scheitert
Ein 454 4.7.0 Temporary authentication failure muss nicht an falschen Zugangsdaten liegen. Im OSPO-Projekt lag es an der Absenderdomain: DMARC mit p=reject und ein SPF-Record mit mehr als den erlaubten zehn DNS-Lookups (RFC 7208). Die SPF-Prüfung endet dann mit einem PermError, und das Relay lehnt die Anmeldung vorsorglich ab. Vor der Fehlersuche an den Zugangsdaten also die DNS-Einträge der Absenderdomain prüfen.