SSH für WordPress-Entwickler: 10 Befehle, die Ihr Leben retten

SSH für WordPress-Entwickler: 10 Befehle, die Ihr Leben retten

Zuletzt überprüft: 22. September 2026
10 Min. Lesezeit
Leitfaden
Full-Stack-Entwickler

Als WordPress-Entwickler verbringen Sie wahrscheinlich viel Zeit im FTP-Client (FileZilla) oder im Hosting-Panel. Das ist ein Fehler. Was in FTP 15 Minuten dauert (z. B. das Löschen eines cache-Ordners mit 100.000 Dateien), dauert im SSH-Terminal 2 Sekunden.

In diesem Leitfaden zeige ich Ihnen eine Reihe von Befehlen, ohne die Senior-Entwickler nicht arbeiten können.


#Vor den zehn Befehlen: Anmeldung per Schlüssel statt Passwort

Alles Folgende setzt voraus, dass Sie bereits auf dem Server sind, und die Art der Anmeldung entscheidet darüber, ob Sie das hier überhaupt nutzen werden. Eine Passwortabfrage bei jeder Verbindung ist genau die Reibung, die Sie zurück in den FTP-Client treibt. Erzeugen Sie ein Paar mit ssh-keygen -t ed25519, übertragen Sie den öffentlichen Teil mit ssh-copy-id user@server, und die Anmeldung schrumpft auf ein Wort. Nehmen Sie ed25519 und nicht das alte RSA mit 2048 Bit, die Schlüssel sind kürzer und die Prüfung ist schneller. Wer mehrere Kundenserver betreut, legt jeden davon mit eigenem Host-Block und eigener IdentityFile-Zeile in ~/.ssh/config ab. Das verhindert den Fall, in dem der Client nacheinander alle vorhandenen Schlüssel anbietet und der Server nach ein paar Fehlversuchen die Verbindung abbricht, bevor der richtige an der Reihe war.


#1. Festplattenanalyse: Was frisst meinen Speicher?

Wenn das Hosting “Quota Exceeded” schreit, hilft FileZilla nicht. Nutzen Sie dies:

#du (Disk Usage)

## Ordner im aktuellen Verzeichnis nach Größe sortiert anzeigen
du -h --max-depth=1 | sort -hr

#ncdu (NCurses Disk Usage)

Wenn möglich, nutzen Sie ncdu. Es ist ein interaktiver Manager, den Sie mit Pfeiltasten steuern. Absolute Empfehlung. Zu du greifen Sie, wenn Sie eine Zahl für das Ticket brauchen, zu ncdu, wenn Sie noch nicht wissen, wonach Sie suchen. Beide laufen durch den gesamten Verzeichnisbaum, und das ist nicht umsonst: bei einem großen uploads-Ordner beschäftigen sie die Platte eine Minute lang, was sich auf Shared Hosting als langsamere Seitenauslieferung bemerkbar macht. Zeigen Sie deshalb auf ein Unterverzeichnis statt auf das Kontoverzeichnis, solange die Seite Besucher hat. Ob der Platz freigegeben werden darf, sagt Ihnen keiner der beiden. Bei einem Multisite lohnt der erste Blick auf wp-content/uploads/sites, weil dort die Mediathek jeder einzelnen Instanz liegt und eine längst stillgelegte Subsite ihre Bilder trotzdem behält.


#2. Logs: Echtzeit-Debugging

Statt debug.log herunterzuladen, mit Notepad zu öffnen und nach Fehlern zu suchen… schauen Sie live zu!

#tail -f

## Die letzten Zeilen der Datei in Echtzeit verfolgen
tail -f wp-content/debug.log

Aktualisieren Sie jetzt die Seite im Browser, und Fehler erscheinen direkt auf dem Bildschirm. Beenden mit Strg+C. Live mitzulesen lohnt sich, solange Sie den Fehler auf Kommando auslösen können. Wenn nicht, ist die gesuchte Zeile längst durchgelaufen, und Sie steigen besser mit tail -n 200 wp-content/debug.log ein und lesen rückwärts. Trennen Sie außerdem zwei Dinge, die gern verwechselt werden: wp-content/debug.log schreibt WordPress selbst und nur dann, wenn WP_DEBUG_LOG in der wp-config.php aktiv ist, während das error_log des Hosters auch die Fehler enthält, die auftreten, bevor PHP überhaupt bis WordPress kommt. Ein weißer Bildschirm ohne Eintrag im ersten Log steht meistens im zweiten. Rotiert wird keine der beiden Dateien von allein, und ein Projekt, das bei jedem Aufruf eine Deprecation-Warnung wirft, schreibt sich damit selbst das Kontingent voll.


#3. Dateien durchsuchen: Wo ist dieser Code?!

Suchen Sie, wo add_image_size verwendet wurde? Laden Sie nicht das ganze Projekt herunter.

#grep

## Suche nach dem Begriff "add_image_size" in allen PHP-Dateien rekursiv
grep -r "add_image_size" .

Die Langform nehmen Sie, wenn Sie den Code um den Treffer herum lesen wollen, grep -rl dagegen, wenn Sie nur wissen müssen, welches Plugin für ein Verhalten zuständig ist. Im Theme kostet das praktisch nichts, in wp-content/plugins dagegen einiges, weil die Rekursion in jedes gefundene vendor-Verzeichnis hineinläuft. --include='*.php' und --exclude-dir=node_modules sind die zwei Zusätze, die sich sofort auszahlen. Prüfen Sie einen Treffer, indem Sie die Datei an dieser Stelle öffnen, und nicht, indem Sie die Anzahl der Fundstellen zählen. Derselbe Funktionsname steht im Code des Plugins, im Dokumentationsblock darüber und in der Übersetzungsdatei, und nur eine dieser drei Stellen ist die Definition.


#4. Berechtigungen: “403 Forbidden” beheben

Oft haben Dateien nach einer Migration falsche Rechte. Merken Sie sich die Regel:

  • Verzeichnisse: 755
  • Dateien: 644

#find + chmod

Nicht manuell machen. Automatisieren:

## Setze 755 für alle Verzeichnisse
find . -type d -exec chmod 755 {} \;

## Setze 644 für alle Dateien
find . -type f -exec chmod 644 {} \;

Führen Sie das aus, wenn ein Symptom vorliegt, ein 403 oder ein fehlgeschlagener Upload, und nicht als Routinepflege. Ein pauschales chmod planiert jede bewusst gesetzte Ausnahme, und die wichtigste davon ist die wp-config.php: sie enthält die Datenbankzugangsdaten und gehört auf 640 oder enger statt auf die 644, die die Schleife ihr gerade verpasst hat. Die Schleife fasst außerdem nur an, was Ihrem Shell-Benutzer gehört. Auf einem Server, auf dem der Webserver unter einem anderen Konto läuft, kann sie also gar nichts reparieren und meldet trotzdem keinen Fehler. Kontrollieren Sie mit ls -l wp-config.php und indem Sie die Seite aufrufen, die vorher nicht ging, niemals durch einen zweiten Durchlauf desselben Befehls.


#5. Backups: Schnelles Archiv

Schnelles Backup vor dem Update? Nicht per FTP kopieren. Packen Sie es auf dem Server.

#tar

## Archiv backup.tar.gz aus dem aktuellen Verzeichnis erstellen
tar -czf backup.tar.gz .

Entpacken:

tar -xzf backup.tar.gz

Auf dem Server zu packen ist der richtige Schritt vor einem Plugin-Update, weil das Archiv Ihre Leitung nie sieht. Eine Backup-Strategie ist es nicht: die Datei liegt auf derselben Platte wie die Seite, übersteht also ein misslungenes Update, aber keinen Ausfall des Datenträgers. Setzen Sie --exclude='wp-content/cache', sonst archivieren Sie genau das, was Sie gleich löschen wollten. Und schauen Sie mit tar -tzf backup.tar.gz | head hinein, bevor Sie sich darauf verlassen, denn ein Archiv, das eine volle Platte mitten im Schreiben abgeschnitten hat, sieht im Verzeichnis aus wie jede andere Datei.


#6. Datenbank (WP-CLI)

Wenn WP-CLI auf dem Server liegt, und das sollte es, brauchen Sie phpMyAdmin nicht mehr. Kein Export, der im Browser bei 60 Sekunden abbricht, kein Upload-Limit beim Import.

## Datenbank exportieren
wp db export backup.sql

## Datenbank importieren
wp db import backup.sql

## Datenbank leeren (Vorsicht!)
wp db reset

Der Export landet auf der Serverplatte, nicht in Ihrer Leitung. Bei einem gewachsenen WooCommerce-Shop ist das der Unterschied zwischen einem Dump in Sekunden und einem Browser-Timeout mitten in der Tabelle wp_postmeta. WP-CLI läuft als Ihr Shell-Benutzer und nicht über den Webserver, weshalb Upload-Limits und max_execution_time hier schlicht nicht greifen. Was es nicht ignorieren kann, ist der Umstand, dass die Seite live ist: wp db import verwirft die Tabellen und legt sie neu an, während jemand im Shop bestellt, ein Wartungsfenster gehört also zum Befehl und ist kein Zusatz. Das Ergebnis prüfen Sie mit einem einzigen wp option get siteurl, das sofort und laut scheitert, wenn der Import nur zur Hälfte durchgelaufen ist.


#7. Dateien in Masse löschen

Einen cache-Ordner einer Plugin-Installation mit einer Million kleiner Dateien per FTP zu löschen, kann eine Stunde dauern, weil FTP jede Datei einzeln bestätigt.

#rm

## Ordner und den gesamten Inhalt löschen (kein Zurück!)
rm -rf wp-content/cache/

Dauer: eine halbe Sekunde. Es gibt keinen Papierkorb. Tippen Sie den Pfad nicht aus dem Kopf, sondern lassen Sie ihn per Tabulator vervollständigen, dann kann aus wp-content/cache/ kein wp-content/ werden. Für ein Cache-Verzeichnis ist das der richtige Befehl und für fast alles andere der falsche, weil es keine Rückfrage und hinterher keinen Weg zurück gibt. Die Gewohnheit, die Sie rettet, ist ein vorheriges ls auf denselben Pfad, gelöscht wird erst, wenn die Ausgabe dem entspricht, was Sie erwartet haben. Achten Sie besonders auf das Ende des Pfades, ein versehentliches Leerzeichen macht aus einem Ziel zwei, und das zweite ist meist das übergeordnete Verzeichnis. Auf einer Seite mit Verkehr baut das Plugin seinen Cache beim nächsten Aufruf neu auf, Sie zahlen also mit einem langsamen Seitenaufbau und nicht mit einem Ausfall.


#8. Dateien zwischen Maschinen abgleichen

FTP überträgt jedes Mal alles neu. rsync vergleicht zuerst beide Seiten und schickt nur die Differenz.

#rsync

## Erst trocken laufen lassen: anzeigen, was kopiert würde, nichts ändern
rsync -avzn --exclude 'cache/' ./wp-content/uploads/ user@server:/var/www/beispiel.de/wp-content/uploads/

Wenn die Dateiliste stimmt, lassen Sie das n in -avzn weg. Zwei Details entscheiden hier über den Ausgang. Der Schrägstrich am Ende des Quellpfads bedeutet “der Inhalt dieses Verzeichnisses”; ohne ihn bekommen Sie uploads/uploads. Und --delete spiegelt auch Löschungen, entfernt also auf dem Ziel alles, was lokal fehlt. Von einer veralteten lokalen Kopie aus gestartet, räumt dieser Schalter die Mediathek ab, statt sie abzugleichen. rsync muss außerdem auf beiden Seiten installiert sein, sonst bricht der Befehl sofort ab.


#9. Portweiterleitung: an die Datenbank hinter der Firewall

Managed Hoster schließen MySQL nach außen ab. Port 3306 antwortet nur auf localhost, der Desktop-Client läuft in einen Timeout und im Panel bleibt phpMyAdmin. Sie brauchen keinen offenen Port, Sie brauchen einen Tunnel.

#ssh -L

## Lokalen Port 3307 auf das MySQL des Servers legen, ohne Remote-Shell
ssh -N -L 3307:127.0.0.1:3306 user@server

Lassen Sie dieses Terminal offen und richten Sie TablePlus, DBeaver oder den mysql-Client auf 127.0.0.1:3307. -N heißt “kein entfernter Befehl”, die Sitzung leitet ausschließlich weiter. Genauso erreichen Sie alles andere, was auf dem Server nur lokal lauscht: Redis auf 6379, eine Staging-Anwendung auf 8080, einen Endpunkt, der nie öffentlich sein sollte. Nehmen Sie einen lokalen Port, der wirklich frei ist, denn ssh meldet den fehlgeschlagenen Bind und hält die Sitzung trotzdem offen. Das sieht nach einem funktionierenden Tunnel aus, bis die erste Abfrage hängt.


#10. Domainwechsel: der Trockenlauf vor dem Schreiben

Nach einer Migration steht in der Datenbank weiterhin die alte Domain, und ein guter Teil davon steckt in serialisierten PHP-Arrays, in denen jeder String seine eigene Länge mitführt. Ein einfaches UPDATE ... REPLACE tauscht den Text und lässt die Längenangabe falsch stehen, danach sind Widgets, Theme-Optionen und Page-Builder-Layouts leer. WP-CLI kennt die Serialisierung und zeigt vorher, was es anfassen will.

#wp search-replace --dry-run

## Zählen, was sich ändern würde, nichts schreiben
wp search-replace 'https://staging.beispiel.de' 'https://beispiel.de' --dry-run --all-tables-with-prefix --report-changed-only

Sie bekommen eine Tabelle mit der Trefferzahl je Spalte. Passen die Zahlen zur Erwartung, wiederholen Sie den Befehl ohne --dry-run. --precise erzwingt den langsameren Weg über PHP statt der SQL-Abkürzung und lohnt sich bei verschachtelter Serialisierung, --recurse-objects greift in serialisierte Objekte hinein. Vorher in jedem Fall ein wp db export: search-replace kennt kein Rückgängig.


#Wenn der Hoster nur SFTP anbietet

Manche Shared-Pakete werben mit SSH und liefern SFTP, also Dateiübertragung über dasselbe Protokoll, aber ohne Shell dahinter. Sie merken es in dem Moment, in dem ssh user@host 'ls' mit exec request failed on channel 0 antwortet. Nichts aus diesem Leitfaden, das auf dem Server ausgeführt wird, überlebt das: weder du noch tar noch WP-CLI, weil es keinen Prozess gibt, in dem sie laufen könnten. Die Übertragungsschicht bleibt nutzbar, sftp und rsync darüber schlagen jeden Client mit Fenster, und die Arbeit an der Datenbank wandert zurück in den Browser, zu phpMyAdmin und einem Backup-Plugin. Bevor Sie das hinnehmen, prüfen Sie, ob der Anbieter eine Shell auf einem anderen Port bereitstellt oder sie auf Anfrage freischaltet, denn bei etlichen Hostern ist das eine Einstellung und keine Produktgrenze. Gibt es sie in dem Tarif wirklich nicht, haben Sie ein belastbares Argument für einen Wechsel, weil Ihnen dort jeder Arbeitsablauf aus diesem Text verschlossen bleibt.


#Zusammenfassung

Das SSH-Terminal beißt nicht. Es ermöglicht Ihnen, mit der Geschwindigkeit der Serverfestplatte zu arbeiten, nicht mit Ihrer Internetgeschwindigkeit. Fangen Sie mit ncdu und tail -f an.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Wenn Sie aus dem Artikel konkrete Maßnahmen für Website, Relaunch oder Weiterentwicklung ableiten wollen, definiere ich den Scope und setze ihn um.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Ähnliche Artikel