
🔄 WordPress im Unterverzeichnis: Installation aus dem Stammverzeichnis verschieben und zurück
Eine vertraute Situation: Sie richten eine Entwicklungsseite ein, bauen das Theme auf, verbinden die Inhalte über WP Migrate DB Pro und stellen nach dem Push fest: kaputte Styles, fehlende Bilder und ein nicht funktionsfähiges wp-admin. Der Grund ist fast immer derselbe: Die Produktivumgebung liegt im Root-Verzeichnis, während die Entwicklung in einem Unterverzeichnis liegt (oder umgekehrt), und ein einfaches Suchen-und-Ersetzen der URLs in der Datenbank behebt diesen Unterschied nicht.
Das Problem reicht tiefer, als es scheint: Bei einer Root-Installation verwendet WordPress für alle Links dieselbe Domain (sowohl für Seiten als auch für Mediendateien). Bei einer Installation im Unterverzeichnis stammen die Inhaltslinks von der Website-Adresse, während die Ressourcenlinks (CSS, JS, Bilder) von der WordPress-Adresse kommen. Ein standardmäßiges Suchen-und-Ersetzen in der gesamten Datenbank ersetzt alles einheitlich und zerstört die Hälfte der Pfade.
In diesem Leitfaden finden Sie zwei bewährte Migrationsrouten (hin und zurück) mit spezifischen Suchen-und-Ersetzen-Einstellungen, der Vorbereitung der wp-config.php und der korrekten Reihenfolge der Dateiübertragung. Nach der Lektüre werden Sie entweder Entwicklung und Produktion auf ein einheitliches Schema bringen oder bewusst eine Migration zwischen unterschiedlichen Installationstypen durchführen, ohne ein defektes Frontend zu riskieren.
💡 Kurzübersicht:
- Bestimmen Sie Ihren Installationstyp: Stimmen „WordPress-Adresse" und „Website-Adresse" unter Einstellungen → Allgemein überein?
- Für die Migration vom Unterverzeichnis ins Root: WP_SITEURL in der wp-config fest hinterlegen, eine
/subdir→/-Ersetzung in der Datenbank durchführen, Dateien eine Ebene nach oben verschieben, die index.php im Root aktualisieren - Für die Migration vom Root ins Unterverzeichnis: Nur Pfade zu
/wp-contentin der Datenbank ersetzen, die WordPress-Adresse in den Einstellungen aktualisieren, das Unterverzeichnis anlegen, index.php und .htaccess zurück ins Root kopieren - Nach jeder Migration: Gehen Sie zu Einstellungen → Permalinks und klicken Sie auf „Speichern": Dies baut die URL-Struktur neu auf und leert den Cache
So stellen Sie fest, wo WordPress installiert ist
Wenn Sie WordPress manuell installiert haben, wissen Sie vermutlich noch, ob es im Domain-Root oder in einem Unterverzeichnis wie /wp oder /blog lag. Wurde die Seite jedoch von einem früheren Entwickler übernommen, vom Hosting-Anbieter per Ein-Klick-Installation bereitgestellt oder sind mehrere Jahre vergangen, verblassen die Details.
Der schnellste Weg: Rufen Sie das WordPress-Admin auf, öffnen Sie Einstellungen → Allgemein und sehen Sie sich die Felder „WordPress-Adresse (URL)" und „Website-Adresse (URL)" an. Stimmen die Werte überein, haben Sie eine Root-Installation:

Unterscheiden sich die Felder, ist WordPress in einem Unterverzeichnis installiert (im folgenden Beispiel ist dies /subdir):

Ein zusätzliches Anzeichen für eine Installation im Unterverzeichnis: Beim Einloggen ins Admin enthält die URL ein Unterverzeichnis, zum Beispiel example.com/wp/wp-admin/ anstelle von example.com/wp-admin/.
Warum Sie nicht einfach direkt übertragen können
Der Kern des Problems liegt im dualen URL-System, das WordPress bei Installationen im Unterverzeichnis verwendet. Lassen Sie uns das anhand konkreter Beispiele aufschlüsseln.
Angenommen, Sie haben eine Root-Installation unter example.com. Absolut alle Links in der Datenbank, sowohl zu einem Beitrag /2025/about-page als auch zu einem Bild /wp-content/uploads/photo.jpg, beginnen mit //example.com. Ein standardmäßiges Suchen-und-Ersetzen //example.local → //example.com funktioniert einwandfrei.
Betrachten Sie nun eine Installation im Unterverzeichnis /wp. Der Link zu demselben Beitrag sieht so aus: //example.com/about-page (über die Website-Adresse), während der Link zu demselben Bild //example.com/wp/wp-content/uploads/photo.jpg lautet (über die WordPress-Adresse mit dem Unterverzeichnis). Ein einfaches Ersetzen //example.local → //example.com wird die Mediendateien zerstören: Das System sucht sie ohne /wp im Pfad und erhält einen 404-Fehler.
Die folgende Tabelle zeigt, welche URL-Gruppen in jeder Migrationsrichtung aktualisiert werden müssen:
Richtung | Seiten- und Beitrags-URLs | Medien- und Ressourcen-URLs | Dateipfade in der Datenbank |
|---|---|---|---|
Unterverzeichnis → Wurzel | Ersetzen Sie | Ersetzen Sie | Ersetzen Sie |
Wurzel → Unterverzeichnis | Unverändert lassen | Ersetzen Sie | Ersetzen Sie |
Neben der Datenbank müssen Sie auch Dateien physisch verschieben und die index.php im Wurzelverzeichnis aktualisieren, sonst findet WordPress die wp-blog-header.php nicht. Im Folgenden gehen wir beide Wege Schritt für Schritt durch.
Methode 1: WordPress vom Unterverzeichnis in die Wurzel verschieben
Dies ist die einfachere Richtung: Sie entfernen das Unterverzeichnis aus den Pfaden, und alle URLs werden „flach", wie bei einer Standardinstallation.
Schritt 0: Diagnose, was schiefgehen wird
Bevor Sie eingreifen, hilft es, sich das Ausmaß des Problems mit eigenen Augen anzusehen. Der folgende Screenshot zeigt die Migrationseinstellungen von wp-in-a-subdirectory.local (WordPress in /subdir) zu wp-standard-install.local (Wurzelinstallation). Die Einstellungen von WP Migrate DB Pro sind Standard, ergänzt um eine Ersetzung des Seitentitels zur Demonstration:

Das Ergebnis ist erwartungsgemäß ernüchternd: Seiten öffnen sich, aber ohne Styles und mit defekten Bildern:

Im HTML sehen Sie Ressourcen-Links mit einem toten /subdir-Pfad, der auf dem Zielserver nicht mehr existiert. Der Versuch, auf wp-admin zuzugreifen, führt zu einer Weiterleitung auf wp-standard-install.local/subdir/wp-login.php, aber eine solche Datei existiert nicht. Beheben wir das nun.
Schritt 1: Vorbereitung
Schützen Sie zunächst den Admin-Zugang während der Migration. Fügen Sie Konstanten in die wp-config.php ein, die Einstellungen aus der Datenbank überschreiben, sodass WordPress Sie auch nach der Datenbankbereinigung weiterhin über den alten Pfad mit dem Unterverzeichnis ins Admin einlässt:
1 define( 'WP_SITEURL', 'http://wp-in-a-subdirectory.local/subdir' ); 2 define( 'WP_HOME', 'http://wp-in-a-subdirectory.local' );
Versetzen Sie die Seite dann in den Wartungsmodus: Bearbeiten Sie die index.php im öffentlichen Wurzelverzeichnis, kommentieren Sie die Zeile require( dirname( __FILE__ )... aus und fügen Sie nach dem schließenden ?>-Tag einen HTML-Platzhalter mit einer kurzen Downtime-Meldung ein. Besucher sehen dann dies:

Sie selbst greifen unterdessen weiterhin über http://wp-in-a-subdirectory.local/subdir/wp-admin/ auf das Admin zu, weil die Konstante WP_SITEURL wirkt.
Schritt 2: Suchen und Ersetzen in der Datenbank
Bereinigen Sie nun die Datenbank. Führen Sie ein Suchen-und-Ersetzen mit diesen Paaren durch (dargestellt in der Oberfläche von WP Migrate DB Pro, aber dasselbe Prinzip funktioniert mit WP-CLI search-replace oder SQL-Abfragen via phpMyAdmin):
//wp-in-a-subdirectory.local/subdir→//wp-in-a-subdirectory.local/app/public/subdir→/app/public(Dateipfad auf dem Server)

Unmittelbar nach der Migration ändert sich das Erscheinungsbild nicht (die Wartungsseite ist weiterhin aktiv, der Admin-Bereich funktioniert über die hartcodierte Konstante). Wenn Sie jedoch die Beitragsinhalte betrachten, werden Bilder noch nicht geladen und interne Links haben das Unterverzeichnis „verloren", was genau dem entspricht, was wir in dieser Phase erreichen wollten:

Schritt 3: physischer Dateitransfer
Entfernen (oder kommentieren) Sie die Zeilen mit WP_SITEURL und WP_HOME aus der wp-config.php. Der Admin-Bereich wird nun nicht mehr funktionieren, verschieben Sie daher die Dateien sofort aus dem Unterverzeichnis eine Ebene nach oben.
Per SSH oder Kommandozeile auf dem Server erledigen Sie das mit drei Befehlen:
1 rm index.php && mv subdir/* . && rm -rf subdir
Per FTP oder mit dem Dateimanager des Hostings ziehen Sie den gesamten Inhalt des Unterverzeichnisses in das öffentliche Wurzelverzeichnis und ersetzen dabei die index.php:

Fertig. Die Website öffnet sich unter der Root-URL; Bilder und Styles sind an ihrem Platz:

Letzter Feinschliff: Rufen Sie den Admin-Bereich auf (jetzt unter http://wp-in-a-subdirectory.local/wp-admin ohne das Unterverzeichnis), öffnen Sie Einstellungen → Permalinks und klicken Sie auf „Änderungen speichern", auch wenn Sie nichts geändert haben. WordPress baut die URL-Struktur neu auf und leert den Cache.
Methode 2: WordPress vom Wurzelverzeichnis in ein Unterverzeichnis verschieben
Viele Entwickler betrachten die Installation von WordPress in einem Unterverzeichnis als bewährte Praxis: Die Kerndateien überfrachten nicht das Wurzelverzeichnis, die Verwaltung via Git/Composer wird vereinfacht und die Domain selbst kann für andere Anwendungen genutzt werden. Eine bestehende Website in ein Unterverzeichnis zu migrieren ist jedoch objektiv komplexer als der umgekehrte Weg, denn nun MÜSSEN einige Links das Unterverzeichnis enthalten, während andere es nicht dürfen.
Schritt 0: Diagnose
Gleicher Ausgangspunkt: Wir versuchen eine Standardmigration von der Wurzelverzeichnis-Installation wp-standard-install.local in die Unterverzeichnis-Installation wp-in-a-subdirectory.local (WordPress in /subdir):

Das Ergebnis ist vollkommen erwartbar: Seiten werden geöffnet, aber Styles und Bilder sind defekt, weil /subdir nicht zu ihren Pfaden hinzugefügt wurde:

Anders als im ersten Szenario funktionieren Links zu Beiträgen und Seiten korrekt (sie sollten das Unterverzeichnis nicht enthalten). Was fehlschlägt, sind speziell Ressourcen (CSS, JS, Medien), deren Pfade nun /subdir enthalten müssen.
Schritt 1: Vorbereitung
In diesem Stadium setzen wir die Konstanten WP_SITEURL und WP_HOME NICHT, da unser Search-Replace diese Werte nicht anfassen wird und wir die WordPress-Adresse etwas später manuell aktualisieren.
Richten Sie die Wartungsseite auf dieselbe Weise ein: Kommentieren Sie require(...) in der index.php aus und fügen Sie einen HTML-Platzhalter hinzu. Besucher sehen die Wartungsmeldung, während Sie weiterhin unter http://wp-standard-install.local/wp-admin/ auf das Backend zugreifen.
Schritt 2: Selektives Search-Replace in der Datenbank
Der entscheidende Unterschied zur ersten Methode: Wir ersetzen NUR Datei- und Ressourcenpfade, OHNE Seiten-URLs anzutasten. Zielen Sie dazu mit dem Muster /wp-content auf die Ersetzung:
//wp-standard-install.local/wp-content→//wp-standard-install.local/subdir/wp-content/app/public→/app/public/subdir(Pfad auf dem Server)

Prüfen Sie nach der Migration den Beitragsinhalt: Links zu anderen Seiten der Website enthalten das Unterverzeichnis NICHT (korrekt), während eingebettete Bilder es enthalten (ebenfalls korrekt):

Schritt 3: WordPress-Adresse aktualisieren und Dateien verschieben
Gehen Sie nun zu Einstellungen → Allgemein und hängen Sie das Unterverzeichnis an das Ende der „WordPress-Adresse (URL)" an, zum Beispiel http://wp-standard-install.local/subdir. Unmittelbar nach dem Speichern wird das Backend ausfallen, weil WordPress versucht, Dateien unter dem neuen Pfad zu finden, diese aber noch nicht dort sind:

Erstellen Sie das Unterverzeichnis subdir im öffentlichen Wurzelverzeichnis und verschieben Sie ALLE WordPress-Dateien hinein. Kopieren Sie anschließend index.php und .htaccess ZURÜCK ins Wurzelverzeichnis, damit die Wartungsseite weiterhin angezeigt wird, während wir fertigstellen:

Stellen Sie die index.php INNERHALB des Unterverzeichnisses in ihren Werkszustand zurück: Entfernen Sie den HTML-Platzhalter und heben Sie die Auskommentierung der require-Zeile auf:
1 <?php 2 define( 'WP_USE_THEMES', true ); 3 require( dirname( __FILE__ ) . '/wp-blog-header.php' );
Nun ist das Backend wieder unter http://wp-standard-install.local/subdir/wp-admin/ erreichbar:

Prüfen Sie den Inhalt: Bilder sind vorhanden, Styles werden geladen:

Letzter Schliff: root index.php
Es bleibt nur noch, die index.php im öffentlichen Root zu aktualisieren. Entfernen Sie die Wartungsseite und geben Sie den korrekten Pfad zu wp-blog-header.php unter Berücksichtigung des Unterverzeichnisses an:
1 <?php 2 define( 'WP_USE_THEMES', true ); 3 require( dirname( __FILE__ ) . '/subdir/wp-blog-header.php' );
Die Website öffnet sich unter der Root-URL, wobei alle Ressourcen aus dem Unterverzeichnis geladen werden:

Gehen Sie erneut zu Einstellungen → Permalinks und speichern Sie ohne Änderungen, damit WordPress die URL-Struktur aktualisiert.
Alternative Werkzeuge und die offizielle Methode
Der oben beschriebene Ansatz mit WP Migrate DB Pro ist komfortabel, aber nicht die einzige Option. Hier sind weitere Werkzeuge, mit denen Sie arbeiten können:
WP-CLI
search-replace. Der Befehlwp search-replace '//oldsite.local/subdir' '//newsite.com'mit dem Flag--dry-runzeigt zunächst an, wie viele Vorkommen ersetzt werden. Für selektive Ersetzung (Root → Unterverzeichnis) grenzen Sie das Muster ein:wp search-replace '//newsite.com/wp-content' '//newsite.com/subdir/wp-content'.Offizielle WordPress-Methode. Die Dokumentation auf developer.wordpress.org beschreibt das Verfahren "Giving WordPress Its Own Directory" mit detaillierten Konfigurationen für Apache (.htaccess), nginx (Server-Block) und IIS (web.config). Die Methode benötigt keine Plugins und funktioniert auf jedem Hosting.
Manuelles SQL. Wenn der Umfang der Änderungen gering ist, können Sie
UPDATE wp_posts SET post_content = REPLACE(post_content, '/subdir/', '/')direkt in phpMyAdmin ausführen, jedoch immer mit vorherigem Backup, da eine solche Ersetzung serialisierte Daten in wp_options und wp_postmeta zerstört.
Welches Werkzeug Sie auch wählen, die Regel ist dieselbe: Bei der Migration ROOT → UNTERVERZEICHNIS ersetzen Sie nur /wp-content und Dateipfade; bei der Migration UNTERVERZEICHNIS → ROOT ersetzen Sie alles, was auf das Unterverzeichnis verweist.
⁉️🤔 Häufig gestellte Fragen
Ist WP Migrate DB Pro für diese Art der Migration erforderlich?
Nein. WP Migrate DB Pro bietet lediglich eine komfortable Oberfläche für Search-Replace mit Verständnis für serialisierte PHP-Daten. Technisch können Sie dieselben Ersetzungen via WP-CLI durchführen (der Befehl
wp search-replacebehandelt serialisierte Strings ebenfalls korrekt) oder die offizielle WordPress-Methode mit manuellem Dateitransfer und Bearbeitung der index.php nutzen. Das Plugin spart Zeit bei großen und mittleren Projekten mit vielen Vorkommen.
Was tun, wenn nach der Migration einige Bilder immer noch nicht laden?
Die häufigste Ursache: Hartcodierte URLs mit absoluten Pfaden vom alten Server sind in der Datenbank verblieben und entsprachen nicht dem Ersetzungsmuster. Prüfen Sie den Beitragsinhalt via phpMyAdmin:
SELECT ID, post_content FROM wp_posts WHERE post_content LIKE '%/subdir/%'(oder die alte Domain). Der zweite Kandidat ist der Browser- und CDN-Cache: Leeren Sie beides und prüfen Sie im Inkognito-Modus.
Muss ich die.htaccess nach dem Transfer aktualisieren?
Wenn Sie sprechende Permalinks nutzen, ja, aber WordPress erledigt dies automatisch, wenn Sie auf der Seite Einstellungen → Permalinks auf "Speichern" klicken. Falls der Server keine Schreibrechte hat, zeigt WordPress Ihnen den fertigen.htaccess-Inhalt zum manuellen Kopieren an. Stellen Sie bei der Migration in ein Unterverzeichnis sicher, dass die Root-.htaccess (nicht die innerhalb des Unterverzeichnisses) keine Regeln enthält, die mit der neuen Struktur kollidieren.
Ist es möglich, die Migration ohne Ausfallzeit durchzuführen?
Technisch ja, wenn Sie die Methode mit.htaccess-Weiterleitungen nutzen (Methode I aus der offiziellen WordPress-Dokumentation, "Without changing URLs"). Bei diesem Ansatz werden die Dateien in das Unterverzeichnis verschoben, während die Root-.htaccess alle Anfragen nahtlos an den neuen Ort leitet. Besucher bemerken den Umzug nicht. Der Nachteil: Sie bleiben auf derselben Domain, und die Website-URL ändert sich formal nicht (das Unterverzeichnis ist in der Adressleiste nicht sichtbar).
Warum unterstützt WP Migrate DB Pro die Migration zwischen verschiedenen Installationstypen nicht von Haus aus?
Die Entwickler von Delicious Brains haben dies auf GitHub fast drei Jahre lang diskutiert. Der Kern des Problems: Das Plugin wendet EIN Search-Replace-Paar auf die GESAMTE Datenbank an, aber die Migration zwischen Root und Unterverzeichnis erfordert UNTERSCHIEDLICHE Ersetzungen für verschiedene URL-Gruppen (Seiten vs. Ressourcen). Automatisch zu bestimmen, welche URL zu welcher Gruppe gehört, würde ein Parsen der Inhaltsstruktur erfordern, was über einfaches Search-Replace hinausgeht. Daher lautet die aktuelle Empfehlung: Bringen Sie Websites VOR der Migration auf ein einheitliches Installationsschema.

Fazit: Root- oder Unterverzeichnisinstallation?
Die Entscheidung zwischen Root- und Unterverzeichnisinstallation von WordPress läuft im Kern auf einen Zielkonflikt hinaus. Die Root-Installation ist einfacher: weniger bewegliche Teile, direkte Kompatibilität zwischen Dev- und Produktionsumgebung, keine Überraschungen durch doppelte URLs. Die Unterverzeichnisinstallation ist architektonisch sauberer: Die Core-Dateien sind isoliert, nur die index.php liegt im Root, die Aktualisierung von WordPress per Git/Composer ist leichter, und das Hosting mehrerer Anwendungen auf einer Domain ist sicherer.
Wenn Sie eine Produktions- und eine Dev-Site betreiben, bringen Sie beide auf ein einheitliches Schema (egal welches) und vergessen Sie das Problem. Arbeiten Sie in einem Team, in dem manche Projekte historisch im Root liegen, während andere in Unterverzeichnissen laufen, kennen Sie jetzt die exakten Such-Ersetzungs-Muster für jede Richtung.
Die wichtigste Regel zum Merken: Bei der Migration ROOT → UNTERVERZEICHNIS fassen Sie nur /wp-content und Dateipfade an; bei der Migration UNTERVERZEICHNIS → ROOT ersetzen Sie alles, was das Unterverzeichnis enthält. Und klicken Sie nach dem Umzug immer, wirklich immer auf „Speichern" bei den Permalinks.



