Backup und Wiederherstellung für ein Docker-WordPress-Setup: Mein persönlicher Leitfaden

Ich möchte dir zeigen, wie ich mein WordPress-Setup in Docker sichere und sicherstelle, dass ich es jederzeit wiederherstellen kann. Vielleicht hilft dir dieser Leitfaden, deinen eigenen Prozess zu optimieren.


Warum ich regelmässig Backups mache

Datenverlust kann schneller passieren, als man denkt. Egal ob durch einen Hardwarefehler, ein fehlerhaftes Plugin oder versehentliches Löschen – ohne Backup stehst du im Ernstfall mit leeren Händen da.


Mein Docker-Setup

Mein WordPress-Projekt läuft in einer Docker-Compose-Umgebung. Die Konfiguration sieht so aus:

  • wordpress_dimotec: Dieser Dienst enthält die WordPress-Dateien – alles, was unter /var/www/html liegt, wie Themes, Plugins und hochgeladene Bilder. Diese Daten speichere ich lokal im Verzeichnis ./../data/wordpress_dimotec.
  • db_dimotec: Der MySQL-Dienst speichert die dynamischen Inhalte wie Beiträge und Einstellungen. Die Datenbankdaten sind in ./../data/db_dimotec gespeichert.

Hier ist meine wordpress_dimotec.yml, die ich verwende:

services:
  wordpress_dimotec:
    image: wordpress:latest
    container_name: wordpress_dimotec
    depends_on:
      - db_dimotec
    environment:
      WORDPRESS_DB_HOST: db_dimotec
      WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
      WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
    volumes:
      - ./../data/wordpress_dimotec:/var/www/html
    networks:
      - traefik
      - wordpress_dimotec_net
    labels:
      - "traefik.http.routers.wordpress_dimotec.rule=Host(`www.dimotec.ch`)"
      - "traefik.http.routers.wordpress_dimotec.entrypoints=websecure"
      - "traefik.http.routers.wordpress_dimotec.tls.certresolver=myresolver"
    restart: always

  db_dimotec:
    image: mysql:8.0
    container_name: mysql_dimotec
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${WORDPRESS_DB_NAME}
      MYSQL_USER: ${WORDPRESS_DB_USER}
      MYSQL_PASSWORD: ${WORDPRESS_DB_PASSWORD}
    command:
      - "--explicit_defaults_for_timestamp=ON"
      - "--host_cache_size=0"
    volumes:
      - ./../data/db_dimotec:/var/lib/mysql
    networks:
      - wordpress_dimotec_net
    restart: always

volumes:
  wordpress_dimotec_data:
  db_dimotec_data:

networks:
  wordpress_dimotec_net:  
  traefik:

Um sicherzugehen, dass sich die Daten wirklich in den angegebenen Volumes befinden, führe ich die folgenden Prüfungen durch:

1. Docker-Volumes inspizieren

Docker-Compose erstellt automatisch Volumes für die Dienste, falls diese in der Konfiguration angegeben sind. Um eine Übersicht über die Volumes zu bekommen, führe ich diesen Befehl aus:

docker volume ls

Die Ausgabe zeigt alle existierenden Docker-Volumes an, einschliesslich derer, die für wordpress_dimotec und db_dimotec erstellt wurden. Ein typischer Eintrag könnte so aussehen:

DRIVER    VOLUME NAME
local     <projectname>_wordpress_dimotec_data
local     <projectname>_db_dimotec_data

2. Daten aus den Volumes prüfen

Die Inhalte eines Volumes kannst du über den entsprechenden Container prüfen. Hier sind die Schritte:

Prüfen des WordPress-Datei-Volumes: Starte den WordPress-Container (falls er nicht läuft):

docker compose -f wordpress_dimotec.yml up -d 

Wechsle in den Container und prüfe den Inhalt des Verzeichnisses /var/www/html:

docker exec -it wordpress_dimotec bash ls -la /var/www/html

Hier siehst du eine Liste aller WordPress-Dateien, wie z. B. wp-config.php, Plugins, Themes und Medien. Wenn die Dateien mit dem Inhalt in ./../data/wordpress_dimotec übereinstimmen, ist das Volume korrekt gemountet.

Prüfen des MySQL-Datenbank-Volumes: Starte den MySQL-Container (falls er nicht läuft):

docker compose -f wordpress_dimotec.yml up -d 

Wechsle in den Container und prüfe den Inhalt des Datenbankverzeichnisses /var/lib/mysql:

docker exec -it mysql_dimotec bash ls -la /var/lib/mysql

Du solltest Dateien sehen, die zu deiner MySQL-Datenbank gehören, wie z. B. .ibd– und .frm-Dateien, sowie eine ibdata1-Datei. Diese Dateien repräsentieren die physische Speicherung der Datenbankinhalte.


3. Daten mit dem Host abgleichen

Prüfe, ob die Dateien in den Host-Verzeichnissen tatsächlich mit den Daten im Container übereinstimmen. Öffne dazu die entsprechenden Verzeichnisse auf deinem Host:

  • Für WordPress: ls -la ./../data/wordpress_dimotec
  • Für MySQL: ls -la ./../data/db_dimotec

Vergleiche die Ausgabe mit den Inhalten, die du im Container geprüft hast. Dies bestätigt, dass die Volumes korrekt gemountet und die Daten auf dem Host verfügbar sind.


Warum ist das wichtig?

Diese Prüfungen geben mir Sicherheit, dass die Daten, die ich sichern möchte, tatsächlich am angegebenen Ort gespeichert sind. Zudem erleichtert es das Debugging, falls es zu Problemen mit den Volumes oder der Datenpersistenz kommt.


Wie ich ein Backup erstelle

1. Container stoppen

Um sicherzustellen, dass keine Änderungen während des Backups vorgenommen werden, stoppe ich zuerst die Docker-Container:

docker compose -f wordpress_dimotec.yml down

2. WordPress-Dateien sichern

Die Dateien, die WordPress benötigt, liegen in meinem ./../data/wordpress_dimotec-Verzeichnis. Dieses packe ich in eine komprimierte Datei:

cd ./backup
tar -czvf wordpress_dimotec_volume_backup.tar.gz -C ./../data/wordpress_dimotec .

3. Datenbank sichern

Die Datenbank ist genauso wichtig wie die Dateien. Dazu starte ich den WordPress Service wieder:

docker compose -f wordpress_dimotec.yml up -d

Anschliessend erstelle ich einen SQL-Dump:

cd ./backup
docker exec mysql_dimotec mysqldump -u ${WORDPRESS_DB_USER} -p${WORDPRESS_DB_PASSWORD} ${WORDPRESS_DB_NAME} > wordpress_dimotec_db_backup.sql

Ich verwende dabei die Umgebungsvariablen aus meiner .env-Datei, um die Zugangsdaten nicht direkt im Skript zu hinterlegen.

4. Backups organisieren

Ich speichere die Backups in einem separaten Ordner und beschrifte sie mit dem aktuellen Datum:

/backup/
├── wordpress_dimotec_volume_backup.tar.gz
├── wordpress_dimotec_db_backup.sql

Wie ich sicherstelle, dass mein Backup funktioniert

Ich möchte eine einfache Testumgebung mit docker-compose aufsetzen, die über localhost erreichbar ist. Dafür erstelle ich eine separate wordpress_dimotec_backuptest.yml Datei speziell um die Testinstanz zu erstellen.


1. Test-Setup erstellen

Für die Testumgebung erstelle ich eine separate wordpress_dimotec_backuptest.yml im selben Verzeichnis. Diese Datei enthält eine minimale Konfiguration:

services:
  traefik:
    image: traefik:v2.6
    container_name: traefik
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
    networks:
      - wordpress_dimotec_net

  test_wordpress_dimotec:
    image: wordpress:latest
    container_name: backuptest_wordpress_dimotec
    depends_on:
      - backuptest_db_dimotec
    environment:
      WORDPRESS_DB_HOST: backuptest_db_dimotec
      WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
      WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
    volumes:
      - ./../data/backuptest_wordpress_dimotec:/var/www/html
    labels:
      - "traefik.http.routers.backuptest.rule=Host(`localhost`)"
      - "traefik.http.routers.backuptest.entrypoints=web"
    networks:
      - wordpress_dimotec_net
    restart: always

  backuptest_db_dimotec:
    image: mysql:8.0
    container_name: backuptest_mysql_dimotec
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${WORDPRESS_DB_NAME}
      MYSQL_USER: ${WORDPRESS_DB_USER}
      MYSQL_PASSWORD: ${WORDPRESS_DB_PASSWORD}
    command:
      - "--explicit_defaults_for_timestamp=ON"
      - "--host_cache_size=0"
    volumes:
      - ./../data/backuptest_db_dimotec:/var/lib/mysql
    networks:
      - wordpress_dimotec_net
    restart: always

networks:
  wordpress_dimotec_net:

2. Backups wiederherstellen

Alte Daten löschen

Ich lösche alle alten Daten, falls vorhanden

sudo rm -rf ./data/backuptest_*
Datenbank wiederherstellen

Ich starte die Testdatenbank mit docker compose

docker compose -f wordpress_dimotec_backuptest.yml up -d backuptest_db_dimotec

und erstelle eine Datenbank mit demselben Namen aus dem produktiven System

docker exec -i backuptest_mysql_dimotec mysql -u root -ptestpassword -e "CREATE DATABASE <WORDPRESS_DB_NAME>;"

Anschliessend importiere ich den SQL-Dump in die Testdatenbank:

cd ./backup
docker exec -i backuptest_mysql_dimotec mysql -u root -ptestpassword ${WORDPRESS_DB_NAME} < wordpress_dimotec_db_backup.sql
WordPress-Dateien wiederherstellen

Ich kopiere die WordPress-Dateien aus dem Backup-Verzeichnis in die Testumgebung:

cd ./data
mkdir backuptest_wordpress_dimotec
tar -xzvf ./../backup/wordpress_dimotec_volume_backup.tar.gz -C ./backuptest_wordpress_dimotec

3. Testinstanz starten

Ich starte die gesamte Testumgebung:

docker compose -f wordpress_dimotec_backuptest.yml up -d

Jetzt läuft die Testinstanz unter http://localhost. Dafür öffne ich den Webbrowser und überprüfe das.

4. http://localhost/wp-admin/ funktioniert (noch) nicht

Nach der Wiederherstellung kann ich die Startseite meiner WordPress-Installation unter http://localhost aufrufen. Aber der Aufruf http://localhost/wp-admin/ funktioniert nicht. Dies liegt daran, dass die URLs in der Datenbank noch nicht korrekt sind.

Verbindung zur Datenbank herstellen:

docker exec -it backuptest_mysql_dimotec mysql -u ${WORDPRESS_DB_USER} -p${WORDPRESS_DB_PASSWORD}

Aktuelle URLs prüfen:

USE ${WORDPRESS_DB_NAME};
SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl', 'home');

URLs korrigieren:

UPDATE wp_options SET option_value = 'http://localhost' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'http://localhost' WHERE option_name = 'home';

Service neu starten

docker compose -f wordpress_dimotec_backuptest.yml down 
docker compose -f wordpress_dimotec_backuptest.yml up -d

Erneut testen: Nach diesem Schritt funktionierte der Zugriff auf http://localhost/wp-admin/ einwandfrei.

5. Cleanup nach dem Test

Nachdem du geprüft hast, ob das Backup funktioniert, kannst du die Testumgebung wieder herunterfahren und die Testdaten löschen:

docker compose -f wordpress_dimotec_backuptest.yml down -v

Warum dieses Setup so praktisch ist

  • Schnell einsatzbereit: Die separate wordpress_dimotec_backuptest.yml vermeidet Konflikte mit der Produktionsumgebung.
  • Einfacher Zugriff: Die Testinstanz ist direkt über http://localhost erreichbar, ohne DNS-Einstellungen.
  • Wiederverwendbar: Du kannst diese Testumgebung immer wieder für die Überprüfung neuer Backups nutzen.

Comments

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert