Überarbeitet am 9. September 2026.
Diese Anleitung brauchte dringend eine Überarbeitung. Die alte Version startete das normale WordPress-Apache-Image, konfigurierte anschließend aber einen Nginx-Container so, als würde WordPress auf FastCGI-Port 9000 laufen. Das waren zwei verschiedene Betriebsarten vermischt.
Heute zeige ich den Aufbau, den ich selbst bevorzuge: WordPress und MariaDB laufen in Docker, Nginx läuft bereits auf dem Host als Reverse Proxy.
Voraussetzungen
Docker und das Compose-Plugin sollten bereits installiert sein. Falls nicht, findest du hier meine aktuelle Anleitung: Docker und Docker Compose unter Debian/Ubuntu installieren.
Für das Beispiel verwende ich:
- WordPress 7.1 mit PHP 8.4 und Apache,
- MariaDB 11.8,
- einen externen Nginx auf dem Host,
- die lokale Weiterleitung
127.0.0.1:8080.
Projektverzeichnis anlegen
sudo mkdir -p /opt/wordpress
cd /opt/wordpress
Zugangsdaten in .env ablegen
Passwörter möchte ich nicht direkt in der compose.yaml verteilen. Deshalb lege ich eine .env an:
nano .env
Beispiel:
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wordpress
WORDPRESS_DB_PASSWORD=HIER_EIN_LANGES_ZUFAELLIGES_PASSWORT
MARIADB_ROOT_PASSWORD=NOCH_EIN_LANGES_ZUFAELLIGES_PASSWORT
Danach die Datei vor anderen lokalen Benutzern schützen:
chmod 600 .env
compose.yaml erstellen
nano compose.yaml
Meine schlanke Basis sieht so aus:
services:
db:
image: mariadb:11.8
restart: unless-stopped
environment:
MARIADB_DATABASE: ${WORDPRESS_DB_NAME}
MARIADB_USER: ${WORDPRESS_DB_USER}
MARIADB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 10
wordpress:
image: wordpress:7.1.0-php8.4-apache
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
WORDPRESS_CONFIG_EXTRA: |
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
$_SERVER['HTTPS'] = 'on';
}
ports:
- "127.0.0.1:8080:80"
volumes:
- wp_data:/var/www/html
volumes:
db_data:
wp_data:
Warum nur 127.0.0.1?
Der WordPress-Container muss in diesem Aufbau nicht selbst öffentlich auf Port 8080 erreichbar sein. Nginx sitzt davor und ist der einzige öffentliche Einstiegspunkt.
Deshalb:
127.0.0.1:8080:80
und nicht:
8080:80
Das reduziert unnötig offene Docker-Ports.
Container starten
docker compose up -d
docker compose ps
Die Logs des WordPress-Containers kannst du bei Bedarf so verfolgen:
docker compose logs -f --tail=100 wordpress
Nginx als Reverse Proxy
Wenn Nginx auf dem Host bereits HTTPS und das Zertifikat verwaltet, reicht für WordPress im Kern ein Reverse Proxy auf den lokalen Port.
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name blog.example.de;
ssl_certificate /etc/letsencrypt/live/blog.example.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.example.de/privkey.pem;
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Vor dem Neuladen immer testen:
sudo nginx -t
sudo systemctl reload nginx
WordPress einrichten
Danach rufst du die konfigurierte HTTPS-Domain im Browser auf. Wenn Datenbank und Container gesund sind, erscheint der normale WordPress-Einrichtungsdialog.
Die Datenbank-Zugangsdaten müssen dort nicht nochmals eingegeben werden, weil das offizielle Docker-Image sie bereits aus den Umgebungsvariablen erhält.
Backups: zwei Dinge gehören zusammen
Ein WordPress-Backup besteht nicht nur aus dem Volume wp_data. Ebenso wichtig ist die MariaDB-Datenbank. Ich sichere deshalb immer Dateien und Datenbank.
Die Docker-Volumes allein sind noch kein Backup, solange sie nur auf demselben Server liegen.
Updates
Für neue Container-Images:
docker compose pull
docker compose up -d
Vor größeren WordPress-, PHP- oder Datenbank-Sprüngen würde ich immer ein aktuelles Backup erstellen und die Release-Hinweise prüfen.
Mehr zu Compose selbst findest du in meiner Erklärung Docker Compose: Services, Volumes, Ports und Netzwerke verstehen.
Apache oder FPM?
Das offizielle WordPress-Image gibt es sowohl mit Apache als auch als FPM-Variante. FPM ist interessant, wenn Nginx direkt mit PHP-FPM im privaten Docker-Netz sprechen soll. Das Setup ist aber etwas komplexer, weil Nginx dann auch Zugriff auf die WordPress-Dateien benötigt.
Für einen bereits vorhandenen externen Nginx finde ich den hier gezeigten Apache-Container auf localhost angenehm unkompliziert.
Fazit
Damit ist WordPress sauber getrennt: MariaDB bleibt intern, WordPress ist nur lokal auf Port 8080 erreichbar und der vorhandene Nginx übernimmt Domain, HTTPS und öffentlichen Zugriff. Vor allem ist der Aufbau jetzt technisch konsistent – im Gegensatz zur alten Mischung aus Apache-Image und FastCGI-Konfiguration.
Quelle: Docker Official Image: WordPress.
Gedanken dazu 0 Kommentare
Noch ist es ruhig hier. Dein Gedanke könnte der erste sein.
Was denkst du dazu?
Dein Kommentar erscheint nach der Freigabe.