Wer WordPress zum Testen, für eine Redaktionsumgebung oder als dauerhaften Betrieb aufsetzt, verliert die erste Stunde selten an Inhalten. Meist geht sie für PHP-Versionskonflikte, abweichende Datenbank-Stände und vergessene Server-Einstellungen verloren. Jede Installation weicht leicht von der letzten ab, und diese Abweichung macht Fehler schwer reproduzierbar.
Docker Compose löst dieses Problem, indem es WordPress, Datenbank und Hilfswerkzeuge in einer einzigen Datei bündelt und mit einem Befehl startet. Seit 2023 hat sich dabei die Syntax verändert, ein Detail, das viele ältere Anleitungen noch nicht abbilden. Dieser Beitrag zeigt die aktuelle Einrichtung Schritt für Schritt, inklusive WP-CLI, Migration einer bestehenden Seite und der Frage, wann sich der Eigenbetrieb im Unternehmen überhaupt lohnt.
Das Wichtigste in Kürze
- Befehl geändert: Seit Mitte 2023 heißt der Compose-Befehl
docker compose(ohne Bindestrich) stattdocker-compose[1]. - Aktuelle Datenbank-Basis: WordPress.org empfiehlt Stand 2026 MySQL ab Version 8.0 oder MariaDB ab Version 10.6 [2].
- WP-CLI bleibt Standard: Plugin- und Theme-Installation per Kommandozeile läuft weiterhin über WP-CLI, offiziell als eigenes Docker-Image verfügbar [3][4].
- Migration per Plugin funktioniert weiterhin: All-in-One WP Migration wird 2026 aktiv weiterentwickelt und zählt über 5 Millionen aktive Installationen [5].
- Eigenbetrieb ist eine Dauerentscheidung: Wer selbst hostet, übernimmt Updates, Backups und Sicherheits-Patches dauerhaft. Ein verwaltetes CMS verschiebt diese Aufgaben an den Anbieter.
Docker Compose als technische Basis für WordPress
Der eigentliche Gewinn einer docker-compose.yml liegt in der Reproduzierbarkeit. Dieselbe Datei erzeugt auf dem Laptop des Entwicklers und auf dem Server dieselbe Umgebung, unabhängig davon, welche PHP-Version der Host mitbringt.
Seit Mitte 2023 hat sich dabei ein Detail verändert, das ältere Anleitungen noch nicht abbilden: Der Support für Compose V1 mit dem eigenständigen Befehl docker-compose endete nach Angaben von Docker im Juni 2023 [1]. Seither ist docker compose, ohne Bindestrich und als fester Bestandteil der Docker-CLI, die aktuelle Syntax. GitHub hat den alten Befehl zusätzlich zum 9. Juli 2024 vollständig aus seinen gehosteten Runner-Images entfernt [6]. Alle Befehle in diesem Beitrag nutzen deshalb docker compose; wer noch Skripte mit docker-compose betreibt, sollte sie vor der nächsten Server-Migration anpassen.
WordPress mit Docker Compose einrichten

Systemvoraussetzungen
Für die Einrichtung reichen ein aktueller Docker Engine mit Compose V2, seit 2023 standardmäßig in Docker Desktop und den offiziellen Linux-Paketen enthalten, sowie git zum Anlegen der Projektstruktur. WordPress läuft komplett im Container. PHP, Webserver und Datenbank müssen auf dem Host nicht separat installiert werden.
Unter Linux gehört der eigene Benutzer typischerweise in die Docker-Gruppe, damit docker- und docker compose-Befehle ohne sudo funktionieren. Nach dem folgenden Befehl ist ein Abmelden und erneutes Anmelden nötig, damit die Gruppenmitgliedschaft greift:
1sudo groupadd docker2sudo usermod -aG docker $USER
Compose-Datei und Umgebungsvariablen
Im Projektordner definiert eine docker-compose.yml drei Dienste: WordPress selbst, eine Datenbank und phpMyAdmin für die Datenbank-Verwaltung im Browser. Das offizielle WordPress-Image auf Docker Hub dokumentiert dieses Muster mit mysql:8.0 als Datenbank [3]; MariaDB ab Version 10.6 ist laut WordPress.org ebenso eine aktuell unterstützte Alternative [2] und wird hier verwendet, weil auch das offizielle phpMyAdmin-Image sie in seinem Beispiel führt [7]:
1services:2 wordpress:3 image: wordpress:latest4 restart: always5 ports:6 - "8081:80"7 environment:8 WORDPRESS_DB_HOST: db9 WORDPRESS_DB_USER: wordpress10 WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}11 WORDPRESS_DB_NAME: wordpress12 volumes:13 - ./data/wp-app:/var/www/html14 depends_on:15 - db1617 db:18 image: mariadb:10.1119 restart: always20 environment:21 MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}22 MARIADB_DATABASE: wordpress23 MARIADB_USER: wordpress24 MARIADB_PASSWORD: ${DB_PASSWORD}25 volumes:26 - ./data/mysql:/var/lib/mysql2728 phpmyadmin:29 image: phpmyadmin30 restart: always31 ports:32 - "8080:80"33 environment:34 PMA_HOST: db35 depends_on:36 - db
Die Container sprechen sich über die Dienstnamen aus der Compose-Datei an: WORDPRESS_DB_HOST und PMA_HOST zeigen beide auf db, nicht auf eine IP-Adresse. depends_on legt die Startreihenfolge fest.
Eine .env-Datei im selben Ordner hält die Zugangsdaten außerhalb der Compose-Datei:
1DB_ROOT_PASSWORD=ein-sicheres-passwort2DB_PASSWORD=ein-zweites-sicheres-passwort
Beide Platzhalter vor dem ersten Start durch eigene, ausreichend lange Passwörter ersetzen.
Zugangsdaten landen direkt in der docker-compose.yml und damit in der Versionskontrolle. Sie gehören ausschließlich in die .env-Datei, und die gehört in .gitignore.
Container starten, prüfen und stoppen
1docker compose up -d
Der Parameter -d startet alle drei Container im Hintergrund. Der Ordner data legt dabei die Unterordner wp-app (WordPress-Dateien) und mysql (Datenbankdaten) an, sodass Inhalte einen Neustart überstehen. WordPress ist danach unter http://localhost:8081 erreichbar, phpMyAdmin unter http://localhost:8080. Den Status der Container zeigt docker compose ps; zum Anhalten und vollständigen Entfernen dienen die beiden folgenden Befehle:
1docker compose stop2docker compose down
docker compose stop hält die Container an, docker compose down entfernt sie. In beiden Fällen bleiben die Daten in ./data erhalten, weil sie auf dem Host liegen und nicht im Container. Anders verhält sich down mit der Option -v: Sie löscht zusätzlich die von Compose verwalteten Volumes [8]. Wer diese Option aus einem Beispiel übernimmt, ohne zu prüfen, wo die eigenen Daten liegen, löscht im schlechtesten Fall die Datenbank.
Erst-Einrichtung von WordPress
Zur fertigen Installation führen zwei Wege, der Browser-Wizard unter http://localhost:8081 und die Kommandozeile.
Bei einer einzigen Installation ist der Browser-Wizard der schnellere Weg, weil er ohne Vorbereitung auskommt. Ab der zweiten kippt die Rechnung: Der Wizard verlangt jeden Schritt erneut einzeln, einschließlich Plugin-Auswahl und Konfiguration, während sich die WP-CLI-Befehle in ein Skript schreiben und beliebig oft wiederholen lassen.
Einrichtung per WP-CLI
WP-CLI bleibt das offizielle Kommandozeilen-Werkzeug für WordPress und läuft in einem eigenen Container-Image [4]. Dazu kommt ein weiterer Dienst in die docker-compose.yml:
1 wpcli:2 image: wordpress:cli3 volumes:4 - ./data/wp-app:/var/www/html5 environment:6 WORDPRESS_DB_HOST: db7 WORDPRESS_DB_USER: wordpress8 WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}9 WORDPRESS_DB_NAME: wordpress10 depends_on:11 - db
WordPress-Installation per Kommandozeile:
1docker compose run --rm wpcli wp core install --url=http://localhost:8081 --title="Beispielseite" --admin_user=admin --admin_email=admin@example.com
Plugin installieren und aktivieren, hier am Beispiel des von WordPress selbst gepflegten Demo-Plugins:
1docker compose run --rm wpcli wp plugin install hello-dolly --activate
Theme installieren, hier am Beispiel des aktuellen WordPress-Standardthemes:
1docker compose run --rm wpcli wp theme install twentytwentyfour --activate
Beide Befehle folgen laut WP-CLI-Referenz derselben Struktur [4]:
docker compose run --rm wpcli wp {typ} install {slug} --activate Nur {typ} (plugin oder theme) und {slug} ändern sich — die Struktur bleibt für jedes Plugin oder Theme aus dem WordPress-Verzeichnis gleich.
Migration einer bestehenden Installation
Wer eine bestehende WordPress-Seite in die neue Docker-Umgebung übernehmen will, kommt ohne Handarbeit an Datenbank-Dumps aus, wenn ein Migrations-Plugin Export und Import übernimmt. All-in-One WP Migration bleibt dafür 2026 eine aktiv gepflegte Wahl: Das Plugin zählt über 5 Millionen aktive Installationen und wurde zuletzt vor rund zwei Wochen aktualisiert [5]. Es exportiert Datenbank und Mediathek in eine einzige Datei, die sich im Zielsystem über die Plugin-Oberfläche wieder einspielen lässt.
Vom Testaufbau zum Dauerbetrieb
Das Compose-File aus den vorigen Abschnitten liefert eine reproduzierbare Umgebung für Tests, Redaktionsarbeit und Entwicklung. Für den dauerhaften Betrieb einer öffentlich erreichbaren Seite fehlen vier Dinge, die keine Compose-Datei mitbringt. Sie sind der eigentliche Unterschied zwischen „läuft" und „läuft verantwortbar".
Images an Versionen binden
Im Beispiel oben steht image: wordpress:latest. Für einen Testaufbau ist das bequem, für den Dauerbetrieb ist es die Stelle, an der Reproduzierbarkeit verloren geht: Image-Tags sind veränderlich, ein Anbieter kann denselben Tag später auf ein anderes Image zeigen lassen [9]. Zwei Rechner mit derselben docker-compose.yml können damit unterschiedliche WordPress-Versionen fahren. Das ist der Zustand, den die Datei verhindern soll.
Der Gegenzug ist ein fester Tag statt latest, etwa wordpress:6.8-php8.3-apache, oder für vollständige Festlegung ein Digest in der Form wordpress:6.8@sha256:…, der immer dieselbe Image-Version liefert [9]. Das hat einen Preis, den man kennen sollte: Wer festnagelt, bekommt Sicherheitsaktualisierungen erst dann, wenn er den Tag selbst anhebt [9]. Der nächste Start allein bringt sie nicht mehr mit. Eine offizielle Docker- oder WordPress-Empfehlung gegen latest gibt es nicht; beide Image-Beschreibungen führen den Tag neutral und weisen stattdessen auf regelmäßiges Neubauen hin [3]. Die eigentliche Frage lautet deshalb: Wollen Sie den Zeitpunkt von Versionswechseln selbst bestimmen und dafür einen Termin im Kalender haben, oder wollen Sie ihn dem Image überlassen?
Aktualisieren
Ein Update besteht aus zwei Befehlen. docker compose pull holt die aktuellen Images der Dienste, ohne Container zu starten. docker compose up -d übernimmt die Änderung anschließend, indem es Container mit geändertem Image neu erzeugt, und behält dabei die eingebundenen Volumes [8]:
1docker compose pull2docker compose up -d
Wer nur docker compose pull ausführt, hat nichts aktualisiert und sieht es der Seite nicht an. Sie läuft unverändert auf dem alten Stand weiter, obwohl das neue Image bereits auf dem Host liegt.
Die Daten in ./data überstehen diesen Vorgang. Neu erzeugt wird der Container, nicht der Inhalt. Vor einem Produktiv-Update gehört trotzdem eine Sicherung davor, denn Datenbank-Migrationen von WordPress selbst laufen beim ersten Aufruf nach dem Update und sind nicht ohne Weiteres rückwärts zu drehen.
Sichern und wiederherstellen
Eine Sicherung, die nie zurückgespielt wurde, ist eine Annahme. Zwei Dinge gehören gesichert: die Datenbank und das Verzeichnis wp-content mit Mediathek, Themes und Plugins. Für die Datenbank dokumentiert MariaDB den Weg über den laufenden Container [10]:
1docker compose exec db sh -c 'mariadb-dump --all-databases -u root -p"$MARIADB_ROOT_PASSWORD"' > backup/db.sql
Der Weg zurück nutzt denselben Mechanismus:
1docker compose exec -T db sh -c 'mariadb -u root -p"$MARIADB_ROOT_PASSWORD"' < backup/db.sql
Der Befehl heißt mariadb-dump, nicht mysqldump. MariaDB hat seine Programme mit Version 10.5 umbenannt und den Kompatibilitäts-Verweis mysqldump ab Version 11.0 aus dem offiziellen Docker-Image entfernt [10]. Im hier verwendeten mariadb:10.11 funktionieren noch beide Namen. Wer beim nächsten Versionssprung auf 11.x geht, muss vorher seine Backup-Skripte anfassen, sonst laufen sie ins Leere.
Ein Restore-Test gehört einmal nach der Einrichtung und danach zum Rhythmus: Dump auf einer zweiten, leeren Umgebung einspielen und die Seite aufrufen. Erst dann ist bekannt, dass die Sicherung trägt.
Eigene Domain und HTTPS
Bis hierhin läuft alles auf http://localhost:8081. Für eine öffentlich erreichbare Seite kommt ein Reverse Proxy davor, der die Domain annimmt, das TLS-Zertifikat hält und die Anfragen an den WordPress-Container weitergibt. Das Compose-Setup selbst bringt kein TLS mit, der gemappte Port liefert reines HTTP [3].
Dabei gibt es eine Stolperstelle, die WordPress selbst dokumentiert: Hinter einem Proxy, der TLS beendet, sieht WordPress nur noch eine HTTP-Anfrage und kann bei erzwungenem HTTPS in eine Weiterleitungsschleife laufen. Verhindert wird das über den Header X-Forwarded-Proto, den der Proxy setzt und den WordPress auswerten muss [11]. Das offizielle Image nimmt einem diesen Schritt ab, sofern die von ihm erzeugte wp-config.php verwendet wird [3]. Wer eine eigene wp-config.php mitbringt, ergänzt die Auswertung selbst.
Wenn etwas nicht startet
Zwei Befehle klären die meisten Fälle. docker compose ps listet die Container des Projekts mit Status und veröffentlichten Ports und zeigt mit --all auch die gestoppten [8]. docker compose logs gibt die Ausgabe der Dienste aus, mit -f fortlaufend und mit --tail begrenzt auf die letzten Zeilen [8]:
1docker compose ps --all2docker compose logs -f db
Drei Fehlerbilder erklären sich damit fast immer von selbst. Beendet sich der Datenbank-Container sofort wieder, steht der Grund in seinen Logs, meist ein bereits belegtes Datenverzeichnis oder ein fehlendes Passwort aus der .env. Meldet WordPress „Error establishing a database connection", läuft die Datenbank noch nicht oder WORDPRESS_DB_HOST zeigt nicht auf den Dienstnamen db. Startet der Stack gar nicht, ist häufig einer der Ports 8080 oder 8081 auf dem Host belegt; dann hilft ein anderer Wert links vom Doppelpunkt in der Port-Zuordnung.
Ein Sonderfall betrifft Dateirechte. Der Entrypoint des offiziellen Images setzt die Rechte im WordPress-Verzeichnis selbst, aber nur, wenn das Verzeichnis leer ist und noch keine Installation enthält [3]. Wer ein bestehendes Host-Verzeichnis mit fremden Besitzrechten einbindet, wie es das ./data/wp-app-Muster erlaubt, behält dessen Rechte und stößt später auf fehlgeschlagene Uploads oder Updates. In diesem Fall ist das Verzeichnis vor dem ersten Start auf den effektiven Benutzer des Containers zu setzen; die Image-Beschreibung nennt dafür die Kennung 33 für die Debian-Varianten [3].
Docker-Setup einordnen
Passt Docker-Eigenbetrieb zu Ihrer Situation?
Im Erstgespräch ordnen wir ein, ob der Docker-Compose-Weg aus diesem Beitrag zu Ihrem Team und Ihrer Betriebskapazität passt, oder ob ein verwalteter Ansatz Zeit an anderer Stelle freisetzt.
Erstgespräch anfragenDocker-Eigenbetrieb vs. verwaltetes CMS
Wer die vorherigen Schritte durchgeführt hat, betreibt WordPress ab jetzt selbst. Der Docker-Compose-Stack läuft auf einem eigenen oder gemieteten Server, und die Verantwortung für Betrieb und Sicherheit bleibt vollständig im eigenen Haus. Das ist der Preis für die Kontrolle, die Docker gegenüber einem fertigen Hosting-Paket verschafft.
Drei Aufgaben bleiben dabei dauerhaft bestehen:
- WordPress-Core, Theme und Plugins aktuell halten: Ohne regelmäßige Updates öffnen bekannte Sicherheitslücken das System für Angriffe.
- Backups einrichten und testen: Datenbank und Mediathek brauchen eine Sicherung, die sich im Ernstfall verlässlich wiederherstellen lässt.
- Docker-Images selbst aktualisieren: Jede neue Version von wordpress, mariadb oder phpmyadmin kann Änderungen mitbringen, die vor dem Produktiv-Update geprüft werden müssen.
Wer diesen Wartungsaufwand nicht selbst tragen will, hat zwei Wege: ein verwaltetes WordPress-Hosting, das einen Teil der Aufgaben übernimmt, oder ein verwaltetes CMS wie Quandes Canvas, bei dem Updates, Sicherheits-Patches und Infrastruktur beim Anbieter liegen und nicht mehr im eigenen Compose-Stack.
Rechnen Sie mit einem festen Zeitfenster pro Monat für Image-Updates, Plugin-Updates und einen Restore-Test. Gibt es im Team niemanden, dem dieses Fenster verbindlich gehört, wird es nicht stattfinden. Dann ist die Entscheidung gegen den Eigenbetrieb bereits gefallen, unabhängig davon, wie gut das Compose-File aussieht.
Die vorgelagerte Frage, ob Eigenbau oder Beauftragung überhaupt passt, behandelt der Beitrag Website erstellen lassen für KMU. Wer eine bestehende WordPress-Seite ablösen will, findet die Faktoren im Beitrag Website-Relaunch ohne Sichtbarkeitsverlust.
Docker-Eigenbetrieb oder verwaltetes CMS
Welcher Ansatz passt zu Ihrem Unternehmen?
Wir ordnen mit Ihnen ein, wie viel laufende Wartung ein Docker-Eigenbetrieb realistisch bedeutet und ob ein verwaltetes CMS wie Canvas die tragfähigere Grundlage ist.
Strategiegespräch vereinbarenHäufige Fragen zu WordPress mit Docker
Brauche ich noch docker-compose oder docker compose?
Nutzen Sie `docker compose` ohne Bindestrich. Der Support für die alte, eigenständige Version 1 endete nach Angaben von Docker bereits im Juni 2023 [1], und GitHub hat den alten Befehl zum 9. Juli 2024 vollständig aus seinen Runner-Images entfernt [6].
Welche Datenbank passt 2026 zu WordPress in Docker?
MySQL ab Version 8.0 oder MariaDB ab Version 10.6 erfüllen die aktuellen Empfehlungen von WordPress.org [2]. Beide Datenbank-Images stehen offiziell auf Docker Hub bereit.
Wie installiere ich Plugins ohne den Browser-Wizard?
Über WP-CLI im `wordpress:cli`-Container, zum Beispiel mit `docker compose run --rm wpcli wp plugin install <plugin-slug> --activate` [3][4].
Kann ich eine bestehende WordPress-Seite in die Docker-Umgebung übernehmen?
Ja, über ein Migrations-Plugin wie All-in-One WP Migration, das Datenbank und Mediathek in eine einzige Export-Datei packt [5].
Lohnt sich der Docker-Eigenbetrieb für ein Unternehmen?
Das hängt von der verfügbaren Betriebskapazität ab. Wer Updates, Backups und Sicherheits-Patches selbst tragen kann und will, gewinnt Kontrolle. Wer diese Zeit nicht hat, ist mit einem verwalteten CMS oft besser bedient.
Weiterführend

Webpräsenz
Website erstellen lassen für KMU: die Seite, die die richtigen Anfragen bringt
Eine KMU-Website soll nicht mehr, sondern die richtigen Anfragen bringen. Warum Strategie vor Design kommt, woran es bei Relaunch und Conversion liegt und was der erste Schritt ist.

Webpräsenz
Website-Relaunch ohne Sichtbarkeitsverlust: der KMU-Fahrplan
Ein Website-Relaunch verliert Rankings, wenn URL-Mapping und Redirects fehlen. Der Fahrplan für KMU — inklusive der Frage, ob ein Relaunch überhaupt der richtige Schritt ist.

Webpräsenz
Website mit KI erstellen — sinnvoll für KMU?
Website mit KI erstellen: Wo KI im Website-Bau wirklich hilft (Entwürfe, Struktur) und wo nicht (Strategie, die richtigen Anfragen). Plus die Austauschbarkeits-Falle.


