Inhaltsverzeichnis

05.07.2026 · Zuletzt aktualisiert: 26.09.2026 · 7 Min. Lesezeit

WordPress mit Docker einrichten: Docker-Compose-Anleitung für 2026

WordPress mit Docker Compose einrichten: aktueller docker compose-Befehl, WP-CLI-Beispiele und die Abwägung Eigenbetrieb gegenüber einem verwalteten CMS.

Dr. Matthias Klinger

Von den Expert:innen

Dr. Matthias Klinger

7 Min. Lesezeit

Ein Terminal-Bildschirm und drei kleine Container-Boxen auf einem Schreibtisch, verbunden durch dünne Linien; die mittlere Box trägt einen roten Deckel. (Generiertes Bild)

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) statt docker-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

Drei Bausteine auf einem Holzbrett, ein roter Verbindungssteg zwischen dem größten Baustein und dem Datenbank-Baustein markiert die zentrale Abhängigkeit. (Generiertes Bild)
WordPress, Datenbank und phpMyAdmin laufen als eigene Container, verbunden über eine einzige Compose-Datei.

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 docker
2sudo 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:latest
4 restart: always
5 ports:
6 - "8081:80"
7 environment:
8 WORDPRESS_DB_HOST: db
9 WORDPRESS_DB_USER: wordpress
10 WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
11 WORDPRESS_DB_NAME: wordpress
12 volumes:
13 - ./data/wp-app:/var/www/html
14 depends_on:
15 - db
16
17 db:
18 image: mariadb:10.11
19 restart: always
20 environment:
21 MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
22 MARIADB_DATABASE: wordpress
23 MARIADB_USER: wordpress
24 MARIADB_PASSWORD: ${DB_PASSWORD}
25 volumes:
26 - ./data/mysql:/var/lib/mysql
27
28 phpmyadmin:
29 image: phpmyadmin
30 restart: always
31 ports:
32 - "8080:80"
33 environment:
34 PMA_HOST: db
35 depends_on:
36 - db
Wie die drei Dienste zusammenfinden

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-passwort
2DB_PASSWORD=ein-zweites-sicheres-passwort

Beide Platzhalter vor dem ersten Start durch eigene, ausreichend lange Passwörter ersetzen.

Typischer Fehler: Zugangsdaten in der Compose-Datei

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 stop
2docker compose down
Was beim Aufräumen verloren geht und was nicht

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.

Wann sich die Kommandozeile lohnt

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:cli
3 volumes:
4 - ./data/wp-app:/var/www/html
5 environment:
6 WORDPRESS_DB_HOST: db
7 WORDPRESS_DB_USER: wordpress
8 WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
9 WORDPRESS_DB_NAME: wordpress
10 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]:

WP-CLI-Befehlsmuster zum Wiederverwenden

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 pull
2docker compose up -d
Wenn nach dem ersten Befehl Schluss ist

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
Wichtig: Der Befehl heißt mariadb-dump

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 --all
2docker 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 anfragen

Docker-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.

Daumenregel für die Entscheidung

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 vereinbaren

Hä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

Quellen

  1. [1]Docker: New Docker Compose V2 and V1 deprecation https://www.docker.com/blog/new-docker-compose-v2-and-v1-deprecation/
  2. [2]WordPress.org: Requirements https://wordpress.org/about/requirements/
  3. [3]Docker Hub: wordpress, Official Image https://hub.docker.com/_/wordpress
  4. [4]WordPress Developer Resources: WP-CLI Commands https://developer.wordpress.org/cli/commands/
  5. [5]WordPress.org Plugin-Verzeichnis: All-in-One WP Migration and Backup https://wordpress.org/plugins/all-in-one-wp-migration/
  6. [6]GitHub Changelog: GitHub-hosted runner images deprecation notice, Docker Compose v1 https://github.blog/changelog/2024-04-10-github-hosted-runner-images-deprecation-notice-docker-compose-v1/
  7. [7]Docker Hub: phpmyadmin, Official Image https://hub.docker.com/_/phpmyadmin
  8. [8]Docker Docs: Compose CLI Reference (docker compose pull, up, ps, logs) https://docs.docker.com/reference/cli/docker/compose/
  9. [9]Docker Docs: Building best practices, Abschnitt Pin base image versions https://docs.docker.com/build/building/best-practices/
  10. [10]MariaDB Documentation: Container Backup and Restoration https://mariadb.com/docs/server/server-management/automated-mariadb-deployment-and-administration/docker-and-mariadb/container-backup-and-restoration
  11. [11]WordPress Advanced Administration Handbook: HTTPS, Abschnitt Using a Reverse Proxy https://developer.wordpress.org/advanced-administration/security/https/
KI-Unterstützung
Text
Claude Sonnet 5
Bilder
Codex (Bildgenerierung)

Redaktionell geprüft von Dr. Matthias Klinger

Mehr erfahren

Textentwürfe, Strukturvorschläge und Recherchezusammenfassungen entstanden mit Claude Sonnet 5 (Recherche: Claude Sonnet 5) und wurden von Dr. Matthias Klinger vor der Veröffentlichung redaktionell geprüft und freigegeben. Bilder wurden mit Codex (Bildgenerierung) generiert und kuratorisch ausgewählt. Die inhaltliche Verantwortung für Richtigkeit und Vollständigkeit liegt bei der Quandes GmbH.

Unsere KI-Transparenz-Erklärung
WordPress mit Docker einrichten: Docker-Compose-Anleitung