---
title: "WordPress manuell migrieren: Dateien, Datenbank und search-replace"
date: 2026-09-30T22:15:26+02:00
modified: 2026-11-09T14:35:00+01:00
category: wordpress
type: how_to
author: Marcel Schönfelder
canonical: https://s-edv.com/anleitungen/wordpress-manuell-migrieren-dateien-datenbank-search-replace
keywords:
  - WordPress
  - Migration
  - WP-CLI
  - Datenbank
  - Umzug
reading_time: 9
---

# WordPress manuell migrieren: Dateien, Datenbank und search-replace

Migrations-Plugins sind bequem, scheitern aber oft an Größenlimits, Zeitüberschreitungen oder Premium-Funktionen. Der manuelle Weg funktioniert dagegen bei jedem Hoster mit SSH: Dateien kopieren, Datenbank exportieren und importieren, Adressen mit `wp search-replace` umschreiben. Diese Anleitung zeigt den Ablauf so, dass Sie jeden Zwischenschritt prüfen können, und erklärt, warum ein einfaches Suchen und Ersetzen in der SQL-Datei Ihre Website beschädigt. Der komplette Umzug wurde im Labor zwischen zwei WordPress-Instanzen durchgespielt, einschließlich des Fehlers mit serialisierten Daten.

**Kurzfassung:** Exportieren Sie die Datenbank mit `wp db export` und packen Sie `wp-content` mit `tar`. Auf dem Zielserver installieren Sie frische WordPress-Kerndateien, entpacken `wp-content`, tragen die neuen Zugangsdaten in die `wp-config.php` ein und importieren die Datenbank. Danach leitet die Website noch auf die alte Adresse weiter. Ersetzen Sie die Adresse mit `wp search-replace` und `--skip-columns=guid`, niemals per Texteditor oder `sed`, denn das zerstört serialisierte Daten.

## Voraussetzungen

- [ ] **WordPress:** getestet mit WordPress 7.1.2 auf beiden Seiten. Quelle und Ziel sollten dieselbe WordPress-Version haben.
- [ ] **PHP:** auf dem Zielserver mindestens die PHP-Version der Quelle, mindestens 7.4.
- [ ] **Zugriff:** SSH auf Quell- und Zielserver mit WP-CLI (getestet mit WP-CLI 2.12.0), ein Administratorkonto in WordPress und die Zugangsdaten einer leeren Datenbank auf dem Zielserver.
- [ ] **Speicherplatz:** auf beiden Servern mindestens das Doppelte der Größe von `wp-content` plus Datenbank, weil Archiv und entpackte Dateien gleichzeitig vorhanden sind.
- [ ] **Backup:** eine aktuelle, geprüfte Sicherung der Quelle, bevor Sie beginnen. Wie Sie die Datenbank sichern und zurückspielen, zeigt [WordPress-Datenbank mit WP-CLI sichern und wiederherstellen](https://s-edv.com/anleitungen/wordpress-datenbank-wp-cli-sichern-wiederherstellen).
- [ ] **Zeitfenster:** Während des Umzugs sollten keine Bestellungen, Kommentare oder Formulareingaben auf der Quelle eingehen, sonst fehlen sie auf dem Ziel.

## Schritt 1: Quelle prüfen und Datenbank exportieren

Notieren Sie zuerst die Adresse, unter der WordPress auf der Quelle läuft, und die Präfix-Angabe der Tabellen. Beide brauchen Sie später exakt:

```bash
$ cd /var/www/html
$ wp option get siteurl
$ wp option get home
$ wp config get table_prefix
$ wp core version
```

Exportieren Sie dann die Datenbank. `wp db export` nutzt die Zugangsdaten aus der `wp-config.php`, Sie müssen also kein Passwort eingeben. Legen Sie die Datei außerhalb des öffentlichen Verzeichnisses ab, damit niemand sie über den Browser herunterladen kann:

```bash
$ mkdir -p ~/umzug
$ wp db export ~/umzug/datenbank.sql --add-drop-table
```

Im Labor lautete die Ausgabe `Success: Exported to 'wp-content/umzug.sql'.` Die Option `--add-drop-table` sorgt dafür, dass beim Import vorhandene Tabellen gleichen Namens ersetzt werden. Die exportierte Datei enthielt die alte Adresse im Klartext, und zwar auch innerhalb serialisierter Daten, dazu mehr in Schritt 5.

> **Prüfen:** Die Datei `~/umzug/datenbank.sql` ist größer als wenige Kilobyte und beginnt mit einem Kopf wie `-- MariaDB dump` oder `-- MySQL dump`.

## Schritt 2: wp-content packen und übertragen

Die Kerndateien von WordPress (`wp-admin`, `wp-includes` und die Dateien im Hauptverzeichnis) müssen Sie nicht kopieren, sie kommen auf dem Ziel frisch von WordPress.org. Das ist sauberer, weil so keine veränderten Kerndateien mitwandern. Übertragen Sie nur `wp-content` mit Themes, Plugins und Uploads:

```bash
$ cd /var/www/html
$ tar -czf ~/umzug/wp-content.tar.gz wp-content
$ ls -lh ~/umzug/
```

Im Labor ergab das bei einer frischen Installation mit Standard-Themes ein Archiv von etwa 14 MB. Bei echten Websites bestimmen meist die Uploads die Größe. Kopieren Sie beide Dateien auf den Zielserver, zum Beispiel mit `scp` oder `rsync`:

```bash
$ rsync -av --progress ~/umzug/ benutzer@zielserver:~/umzug/
```

Hinweise zu `rsync` und abgebrochenen Übertragungen gibt die Anleitung [rsync über SSH: Daten synchronisieren und migrieren](https://s-edv.com/anleitungen/rsync-ssh-daten-synchronisieren-migrieren). Prüfen Sie außerdem, ob in der `.htaccess` oder der `wp-config.php` der Quelle eigene Einträge stehen, etwa Weiterleitungen, Sicherheitsregeln oder Konstanten. Diese übertragen Sie in Schritt 3 von Hand.

> **Prüfen:** Auf dem Zielserver liegen `datenbank.sql` und `wp-content.tar.gz` mit derselben Größe wie auf der Quelle.

## Schritt 3: Ziel vorbereiten

Laden Sie auf dem Zielserver die Kerndateien in derselben Version wie auf der Quelle und legen Sie die `wp-config.php` mit den Zugangsdaten der neuen Datenbank an:

```bash
$ cd /var/www/html
$ wp core download --version=7.1.2 --locale=de_DE
$ wp config create --dbname=NEUE_DB --dbuser=NEUER_BENUTZER --prompt=dbpass --dbhost=localhost --dbprefix=wp_
```

Mit `--prompt=dbpass` fragt WP-CLI das Passwort ab, statt es in der Befehlszeile zu erwarten, so landet es nicht im Verlauf der Shell. Das Präfix muss dem Wert aus Schritt 1 entsprechen, sonst findet WordPress nach dem Import keine Tabellen. Übernehmen Sie danach eigene Konstanten aus der alten `wp-config.php`, aber nicht die alten Datenbank-Zugangsdaten und Salts, sofern Sie nicht bewusst alle Benutzer angemeldet lassen wollen.

Entpacken Sie anschließend `wp-content` und setzen Sie den Eigentümer auf den Benutzer des Webservers, bei Debian und Ubuntu meist `www-data`:

```bash
$ cd /var/www/html
$ rm -rf wp-content
$ tar -xzf ~/umzug/wp-content.tar.gz
$ chown -R www-data:www-data wp-content
```

Welche Rechte für Dateien und Verzeichnisse richtig sind, beschreibt [Dateirechte in WordPress richtig setzen](https://s-edv.com/anleitungen/wordpress-dateirechte-richtig-setzen-wp-config-chmod-chown).

> **Prüfen:** `wp core verify-checksums` meldet keine veränderten Kerndateien, und unter `wp-content/uploads` liegen die Jahresordner der Medien.

## Schritt 4: Datenbank importieren

Importieren Sie die Datenbank mit WP-CLI:

```bash
$ wp db import ~/umzug/datenbank.sql
$ wp option get siteurl
```

Im Labor meldete der Import `Success: Imported from 'wp-content/umzug.sql'.` Die Abfrage danach zeigte aber noch die alte Adresse. Das ist erwartet, denn die Datenbank weiß nichts vom Umzug. Ein Aufruf der neuen Adresse im Browser führt deshalb zu einer Weiterleitung auf die alte Website. Im Labor antwortete die neue Instanz mit `301` und leitete auf die Adresse der Quelle weiter. Wenn Sie nur diesen Zustand sehen, ist der Umzug nicht gescheitert, sondern noch nicht abgeschlossen.

> **Prüfen:** `wp option get siteurl` gibt die alte Adresse aus, und `wp db tables` listet die Tabellen mit dem erwarteten Präfix.

## Schritt 5: Adressen mit search-replace umschreiben

WordPress speichert viele Einstellungen serialisiert, also als PHP-Zeichenkette mit Längenangabe. Ein Beispiel aus dem Labor-Export:

```plaintext
a:2:{s:3:"url";s:31:"http://127.0.0.1:21753/bild.jpg";s:5:"titel";s:4:"Test";}
```

Die Zahl `31` gibt die Länge der Adresse an. Ändert sich die Adresse durch einfaches Ersetzen, stimmt die Länge nicht mehr, und PHP kann den Wert nicht mehr lesen. Im Labor wurde das mit `sed` in der SQL-Datei nachgestellt. Nach dem Import stand in der Datenbank `s:31:"https://www.neue-domain.example/bild.jpg"`, eine Zeichenkette mit 40 Zeichen bei angegebenen 31. WordPress meldete darauf `Error: Could not get 'widget_test' option. Does it exist?`, obwohl die Option in der Tabelle stand. Bei echten Websites äußert sich das durch verlorene Widget-Einstellungen, leere Theme-Optionen oder zurückgesetzte Plugin-Konfigurationen.

`wp search-replace` dagegen liest serialisierte Werte, ersetzt darin und schreibt sie mit korrekter Länge zurück. Starten Sie immer mit einem Probelauf:

```bash
$ wp search-replace 'https://alt.example.de' 'https://www.neu.example.de' --all-tables --skip-columns=guid --dry-run --report-changed-only
```

Die Option `--skip-columns=guid` empfiehlt das WordPress-Handbuch zur Migration ausdrücklich. Die Spalte `guid` ist eine dauerhafte Kennung jedes Beitrags, die unter anderem Feed-Reader nutzen, und soll sich nicht ändern. Im Labor fand der Probelauf ohne diese Option 11 Treffer, davon 4 in `guid`. Mit der Option blieben 7:

```plaintext
Table        Column        Replacements  Type
wp_options   option_value  3             PHP
wp_posts     post_content  3             SQL
wp_users     user_url      1             SQL
Success: Made 7 replacements.
```

Die Spalte `Type` zeigt `PHP` bei Tabellen mit serialisierten Werten. Die Testoption lautete danach korrekt `{"url":"http://127.0.0.1:21753/bild.jpg","titel":"Test"}`. Führen Sie den Befehl ohne `--dry-run` aus, wenn das Ergebnis des Probelaufs plausibel ist. Wechselt die Website dabei gleichzeitig von `http` auf `https`, ersetzen Sie die komplette Adresse mit Protokoll. Details zu gemischten Inhalten beschreibt [WordPress auf HTTPS umstellen](https://s-edv.com/anleitungen/wordpress-https-umstellen-ssl-mixed-content-beheben).

> **Prüfen:** `wp option get siteurl` zeigt die neue Adresse, und ein erneuter Probelauf mit der alten Adresse findet nur noch Treffer in `guid`.

## Schritt 6: Aufräumen und testen

Leeren Sie Caches und Permalinks, damit keine alten Adressen mehr ausgeliefert werden:

```bash
$ wp cache flush
$ wp rewrite flush
```

Rufen Sie die Website dann im Browser auf und prüfen Sie Startseite, einen Beitrag mit Bildern, das Kontaktformular und die Anmeldung im Backend. Im Labor lieferte die neue Instanz nach dem Ersetzen den Status 200, interne Links im Beitrag zeigten auf die neue Adresse, und ein Bild unter `wp-content/uploads` war erreichbar. Löschen Sie anschließend die Export-Dateien auf beiden Servern, denn sie enthalten die komplette Datenbank mit Benutzerdaten:

```bash
$ rm -rf ~/umzug
```

Stellen Sie erst jetzt die DNS-Einträge um, falls die Domain gleich bleibt, und sperren Sie Eingaben auf der alten Website. Eine Migration ist ein guter Anlass, die laufende Pflege neu zu ordnen: Updates, Backups auf externen Speicher und die Firewall müssen auf dem neuen Server wieder eingerichtet werden. Wer diese Aufgaben nicht selbst im Kalender halten möchte, kann sie abgeben: Die [WordPress-Wartung von wordpressupdate.de](https://wordpressupdate.de/?utm_source=s-edv.com&utm_medium=artikel&utm_campaign=97) übernimmt Updates von WordPress, Plugins und Themes mit Kompatibilitätsprüfung, wöchentliche Backups auf externen Speicher sowie Einrichtung und Wartung der Firewall.

> **Prüfen:** Die Website lädt unter der neuen Adresse ohne Weiterleitung auf die alte, Bilder werden angezeigt, die Anmeldung funktioniert und die Export-Dateien sind gelöscht.

## Typische Fehler

**Neue Website leitet auf die alte Adresse weiter**

`siteurl` und `home` enthalten noch die alte Adresse. Das ist nach dem Import normal, Schritt 5 behebt es.

**Einstellungen oder Widgets fehlen nach dem Umzug**

Die Adresse wurde per Texteditor oder `sed` ersetzt und hat serialisierte Daten beschädigt. Importieren Sie die ursprüngliche Datenbank erneut und verwenden Sie `wp search-replace`.

**`Error establishing a database connection`**

Zugangsdaten oder Host in der `wp-config.php` sind falsch. Prüfen Sie mit `wp db check`.

**WordPress startet die Installation neu**

Das Tabellenpräfix in der `wp-config.php` passt nicht zu den importierten Tabellen. Vergleichen Sie `wp config get table_prefix` mit der Ausgabe von `wp db tables`.

**Bilder fehlen**

Der Ordner `wp-content/uploads` wurde nicht vollständig übertragen, oder der Webserver darf ihn nicht lesen. Prüfen Sie Größe und Eigentümer.

**GUIDs geändert**

Ohne `--skip-columns=guid` ändern sich die Kennungen aller Beiträge, Feed-Reader zeigen alte Beiträge dann erneut als neu an.

## Häufige Fragen

### Geht das auch ohne SSH?

Dateien lassen sich per FTP übertragen, die Datenbank über phpMyAdmin exportieren und importieren. Für das Ersetzen der Adressen brauchen Sie dann ein Werkzeug, das serialisierte Daten beachtet. Das WordPress-Handbuch nennt dafür Plugins wie Better Search Replace. Mit SSH und WP-CLI ist der Weg deutlich einfacher und überprüfbar.

### Muss ich den Kern mit übertragen?

Nein. Frische Kerndateien in derselben Version sind sicherer, weil so keine veränderten Dateien mitwandern. `wp core verify-checksums` bestätigt den sauberen Zustand.

### Was ist mit Multisite?

Multisite-Installationen speichern Adressen zusätzlich in eigenen Tabellen und in der `wp-config.php`. Das Handbuch beschreibt dafür einen eigenen Ablauf.

## Fazit

Ein manueller Umzug besteht aus wenigen, prüfbaren Schritten: Datenbank exportieren, `wp-content` packen, auf dem Ziel frische Kerndateien und neue Zugangsdaten, Import, dann `wp search-replace` mit Probelauf und `--skip-columns=guid`. Der Labortest zeigt, warum Suchen und Ersetzen in der SQL-Datei keine Abkürzung ist. Wer die Pflege auf dem neuen Server abgeben möchte, findet Updates und Backups bei der [WordPress-Wartung](https://wordpressupdate.de/?utm_source=s-edv.com&utm_medium=fazit&utm_campaign=97) von Marcel Schönfelder.

## Weiterführende Anleitungen und Quellen

- [WordPress-Datenbank mit WP-CLI sichern und wiederherstellen](https://s-edv.com/anleitungen/wordpress-datenbank-wp-cli-sichern-wiederherstellen)
- [Staging-Umgebung für WordPress mit WP-CLI einrichten](https://s-edv.com/anleitungen/wordpress-staging-umgebung-wp-cli-einrichten)
- [Domain umziehen ohne Ausfall](https://s-edv.com/anleitungen/domain-umziehen-ohne-ausfall-dns-email-webseite)
- [WordPress-Handbuch: Moving WordPress (englisch)](https://developer.wordpress.org/advanced-administration/upgrade/migrating/)
- [WP-CLI-Handbuch: wp search-replace](https://developer.wordpress.org/cli/commands/search-replace/)
- [WP-CLI-Handbuch: wp db](https://developer.wordpress.org/cli/commands/db/)
