Wenn du “Fehler 29” im Total Commander oder “Zeitüberschreitung der Verbindung” in FileZilla siehst, sendet dir das Universum eine Nachricht. Hör auf, FTP zu nutzen.
2010 war FTP Standard. 2026 ist Drag-and-Drop von Dateien auf einen Produktionsserver rücksichtslos. Es führt zu:
- Downtime: Was passiert, wenn dein Internet ausfällt, während du die
functions.phphochlädst? - Sicherheitsrisiken: FTP sendet Passwörter im Klartext (außer bei FTPS).
- Keine Historie: Wer hat diese Datei geändert? Wann? Warum?
Das direkte Editieren von PHP-Dateien auf einem Liveserver über FTP ist ein permanenter Risikofaktor für Produktivsysteme. Eine moderne Deployment-Pipeline auf Basis von kryptografischen SSH-Schlüsseln, Versionskontrolle mit Git und automatisierten Release-Strategien gewährleistet fehlerfreie Auslieferungen und sofortige Rollbacks im Ernstfall.
Warum FTP für Produktivumgebungen von WordPress unsicher ist
FTP (File Transfer Protocol) überträgt Zugangsdaten und Dateiinhalte unverschlüsselt im Klartext. Jeder Teilnehmer im selben lokalen Netzwerk, an ungesicherten Routern oder auf Shared-Hosting-Knoten kann Passwörter abfangen. Zudem bietet FTP keinerlei Transaktionssicherheit, keine atomare Umschaltung und keine Möglichkeit, Änderungen mehrerer Entwickler konfliktfrei zusammenzuführen.
SFTP und FTPS schließen zwar die Transportverschlüsselung, lösen jedoch nicht die strukturellen Probleme des Workflows. Entwickler wählen geänderte Dateien manuell aus, überschreiben aktive Dateien im laufenden Betrieb und riskieren unvollständige Uploads. Bricht die Netzwerkverbindung mitten in der Übertragung einer zentralen PHP-Datei ab, stürzt die Website mit Fehlern ab oder liefert Besuchern weiße Seiten aus.
Professionelle Entwicklerteams setzen 2026 auf einen dreistufigen Stack: SSH für sicheren Terminalzugriff und schlüsselbasierte Authentifizierung, Git für transparente Versionshistorie und Team-Zusammenarbeit sowie automatisierte Deployment-Pipelines für konsistente Builds und unterbrechungsfreie Releases.
Wie Sie SFTP und SSH-Keys für WordPress konfigurieren
Passwortbasierte SSH-Logins sind das Hauptziel automatisierter Brute-Force-Angriffe. Eine schlüsselbasierte Authentifizierung eliminiert dieses Angriffsrisiko vollständig, da der Server ausschließlich Verbindungen von Clients akzeptiert, die den passenden privaten Schlüssel besitzen.
Generieren eines ED25519-Schlüsselpaars
ED25519-Schlüssel sind kompakter, schneller und kryptografisch robuster als ältere RSA-Schlüssel. Generieren Sie ein dediziertes Schlüsselpaar im lokalen Terminal:
ssh-keygen -t ed25519 -C "[email protected]"Dieser Befehl erzeugt zwei Dateien: ~/.ssh/id_ed25519 (den geheimen privaten Schlüssel, der niemals weitergegeben werden darf) und ~/.ssh/id_ed25519.pub (den öffentlichen Schlüssel, der auf dem Zielserver hinterlegt wird).
Kopieren des öffentlichen Schlüssels auf den Server
Mit ssh-copy-id wird der öffentliche Schlüssel direkt in die Datei ~/.ssh/authorized_keys auf dem Zielserver eingefügt:
ssh-copy-id [email protected]Anschließend erfolgen alle SSH-Verbindungen zu diesem Server automatisch ohne Passworteingabe.
Konfigurieren von ssh-agent und der SSH-Konfigurationsdatei
Um die Passphrase des privaten Schlüssels nicht bei jedem Verbindungsaufbau erneut eingeben zu müssen, initialisieren Sie den ssh-agent:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519Erstellen oder bearbeiten Sie anschließend ~/.ssh/config, um kurze Server-Aliase anzulegen:
Host wppoland-prod
HostName 198.51.100.42
User deploy
IdentityFile ~/.ssh/id_ed25519
Port 22
Host wppoland-staging
HostName 198.51.100.43
User deploy
IdentityFile ~/.ssh/id_ed25519
Port 22Nun reicht der Befehl ssh wppoland-prod für den sofortigen Verbindungsaufbau. Es müssen keine IP-Adressen oder Kennwörter gemerkt werden. Jeder Entwickler im Team muss über ein eigenes Schlüsselpaar verfügen; private Schlüssel werden niemals geteilt.
Wie Sie ein Git-Repository für WordPress sauber strukturieren
Ein häufiger Fehler beim Umstieg von FTP zu Git besteht darin, die gesamte WordPress-Installation samt Kernverzeichnis, Bild-Uploads und Datenbank-Dumps in das Repository einzuchecken. Ein sauberes Projekt trackt ausschließlich den individuell entwickelten Code.
Modulare Repository-Struktur
Im Git-Repository liegen nur eigene Themes, individuelle Plugins und projektbezogene mu-plugins. Der WordPress-Core und externe Drittanbieter-Plugins werden über Composer verwaltet oder verbleiben außerhalb des Repositories:
wordpress-projekt/
├── .gitignore
├── composer.json
├── wp-content/
│ ├── themes/
│ │ └── wppoland-theme/ # versioniert
│ ├── plugins/
│ │ └── wppoland-custom/ # versioniert
│ └── mu-plugins/ # versioniert
└── wp-config.php # NICHT versioniertEssenzielle Ausschlussregeln in gitignore
Die Datei .gitignore schließt WordPress-Core-Dateien, dynamische Benutzer-Uploads und sensible Konfigurationen konsequent aus:
/wp-admin/
/wp-includes/
/wp-content/uploads/
/wp-content/upgrade/
wp-config.php
.env
*.log
node_modules/
vendor/Der Ausschluss von wp-content/uploads/ verhindert, dass das Repository durch Megabytes an Mediendateien unhandlich wird. Mediendateien gehören in Objektspeicher wie Amazon S3 oder Cloudflare R2 oder werden separat synchronisiert.
Verwaltung von WordPress-Abhängigkeiten mit Composer
Durch den Einsatz von Composer und dem Repository WPackagist lassen sich Plugins und Themes als versionierte Abhängigkeiten mit festen Versionsgrenzen deklarieren:
{
"require": {
"wpackagist-plugin/advanced-custom-fields": "^6.0",
"wpackagist-plugin/wordpress-seo": "^22.0",
"wpackagist-plugin/wp-super-cache": "^1.9"
},
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
}
]
}Ein Aufruf von composer install --no-dev --optimize-autoloader auf dem Server oder in der CI-Pipeline garantiert, dass alle Zielumgebungen identische Plugin-Versionen ausführen.
Wie Sie WordPress mit rsync über SSH bereitstellen
Während Git die Quellcode-Historie abbildet, ist rsync das zuverlässigste Werkzeug zur Übertragung kompilierter Build-Artefakte auf den Produktionsserver. Das Tool berechnet Prüfsummen und überträgt ausschließlich veränderte Datenblöcke.
Vergleich von rsync, SCP und FTP
SCP überträgt bei jedem Aufruf die vollständige Datei, selbst wenn sich nur eine einzige Zeile geändert hat. FTP bietet keinerlei differenzielle Synchronisation oder automatische Prüfsummenvalidierung. rsync vergleicht Zeitstempel und Dateigrößen, berechnet binäre Unterschiede und sendet nur die modifizierten Blöcke über eine verschlüsselte SSH-Verbindung.
Sicherer rsync-Deployment-Befehl mit Probelauf
Führen Sie vor jedem Produktiv-Deployment einen Probelauf mit --dry-run durch, um alle betroffenen Dateien vorab zu prüfen:
rsync -avz --dry-run --delete \
--exclude='.git' \
--exclude='wp-config.php' \
--exclude='wp-content/uploads' \
--exclude='.env' \
--exclude='node_modules' \
./dist/ user@server:/var/www/html/Nach erfolgreicher Prüfung entfernen Sie das Flag --dry-run, um die Synchronisation auszuführen:
rsync -avz --delete \
--exclude='.git' \
--exclude='wp-config.php' \
--exclude='wp-content/uploads' \
--exclude='.env' \
--exclude='node_modules' \
./dist/ user@server:/var/www/html/Der Parameter --delete entfernt auf dem Server alle Dateien, die im lokalen Build nicht mehr existieren. Dadurch wird verhindert, dass veralteter PHP-Code oder gelöschte Assets im Produktivverzeichnis verbleiben. Die Ausschlussmuster schützen hochgeladene Mediendateien und Umgebungskonfigurationen vor unbeabsichtigtem Überschreiben.
CI/CD-Pipelines für WordPress mit GitHub Actions
Automatisierte Pipelines über GitHub Actions kompilieren Frontend-Assets, prüfen Kodierungsstandards mit PHP_CodeSniffer und deployen den Code bei jedem Push auf den Hauptzweig vollautomatisch.
name: Deploy WordPress
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Quellcode auschecken
uses: actions/checkout@v4
- name: PHP einrichten
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
tools: composer
- name: Abhängigkeiten installieren
run: composer install --no-dev --optimize-autoloader
- name: PHP-Standards prüfen
run: vendor/bin/phpcs --standard=WordPress wp-content/themes/wppoland-theme/
- name: Frontend-Assets kompilieren
run: |
npm ci
npm run build
- name: Deployment via rsync
uses: burnett01/[email protected]
with:
switches: -avz --delete --exclude='.git' --exclude='wp-config.php' --exclude='wp-content/uploads'
path: ./
remote_path: /var/www/html/
remote_host: ${{ secrets.SSH_HOST }}
remote_user: ${{ secrets.SSH_USER }}
remote_key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Cache leeren
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: wp cache flush --path=/var/www/htmlSensible Zugangsdaten werden in den Repository Secrets von GitHub hinterlegt, sodass keine Kennwörter oder privaten Schlüssel im Quellcode auftauchen.
Wichtige WP-CLI-Befehle für die Administration über SSH
Das Kommandozeilenwerkzeug WP-CLI ermöglicht die vollständige Administration von WordPress direkt über das Terminal via SSH, ohne dass das Administrationsmenü im Browser geöffnet werden muss.
Core-Updates, Plugin-Verwaltung und Datenbankpflege
# WordPress-Core und Datenbank-Schema aktualisieren
wp core update
wp core update-db
# Plugins installieren und aktualisieren
wp plugin install wordpress-seo --activate
wp plugin update --all
wp plugin deactivate wordfence
# MySQL-Tabellen optimieren und reparieren
wp db optimize
wp db repair
# Sicherheitsschlüssel (Salts) in wp-config.php neu generieren
wp config shuffle-salts
# Wartungsmodus für Updates aktivieren
wp maintenance-mode activate
wp maintenance-mode deactivateSicheres Suchen und Ersetzen in der Datenbank
Beim Wechsel von Staging auf Produktion oder beim Ändern von Domain-Namen enthalten WordPress-Datenbanken serialisierte PHP-Arrays in den Tabellen wp_options und wp_postmeta. Ein reines SQL-Suchen-und-Ersetzen zerstört die Längenangaben dieser Arrays und beschädigt Theme- und Widget-Konfigurationen. WP-CLI berechnet die Längen der serialisierten Strings automatisch neu:
wp search-replace 'https://staging.wppoland.com' 'https://wppoland.com' --all-tables --preciseRemote-Ausführung von WP-CLI über SSH-Aliase
In der lokalen Konfigurationsdatei ~/.wp-cli/config.yml lassen sich praktische Verbindungs-Aliase definieren:
@prod:
ssh: [email protected]/var/www/html
@staging:
ssh: [email protected]/var/www/htmlBefehle können anschließend direkt vom Entwicklerrechner ausgeführt werden:
wp @prod plugin list
wp @prod cache flush
wp @prod cron event run --due-nowUmgebungskonfiguration mit phpdotenv und wp-config
Das feste Hinterlegen von Datenbank-Passwörtern in wp-config.php verhindert eine saubere Versionierung. Eine robuste Architektur trennt Konfigurationsparameter strikt vom Anwendungscode mithilfe von Umgebungsvariablen und vlucas/phpdotenv.
Aufbau der .env-Datei für verschiedene Umgebungen
Im Wurzelverzeichnis des Projekts speichert eine lokale .env-Datei alle umgebungsspezifischen Variablen und bleibt vom Git-Tracking ausgeschlossen:
DB_NAME=wppoland_prod
DB_USER=wp_user
DB_PASSWORD=sehr_sicheres_passwort
DB_HOST=localhost
WP_HOME=https://wppoland.com
WP_SITEURL=https://wppoland.com
WP_ENVIRONMENT_TYPE=productionIn der Datei wp-config.php lädt der Autoloader von Composer diese Werte transparent:
<?php
require_once __DIR__ . '/vendor/autoload.php';
if ( file_exists( __DIR__ . '/.env' ) ) {
$dotenv = DotenvDotenv::createImmutable( __DIR__ );
$dotenv->load();
}
define( 'DB_NAME', $_ENV['DB_NAME'] );
define( 'DB_USER', $_ENV['DB_USER'] );
define( 'DB_PASSWORD', $_ENV['DB_PASSWORD'] );
define( 'DB_HOST', $_ENV['DB_HOST'] ?: 'localhost' );
define( 'WP_HOME', $_ENV['WP_HOME'] );
define( 'WP_SITEURL', $_ENV['WP_SITEURL'] );
define( 'WP_ENVIRONMENT_TYPE', $_ENV['WP_ENVIRONMENT_TYPE'] ?: 'production' );
define( 'WP_DEBUG', $_ENV['WP_ENVIRONMENT_TYPE'] !== 'production' );
define( 'WP_DEBUG_LOG', $_ENV['WP_ENVIRONMENT_TYPE'] !== 'production' );
define( 'WP_DEBUG_DISPLAY', false );Dadurch bleibt wp-config.php auf Entwicklungssystemen, im Staging-Workflow und in der Produktionsumgebung völlig identisch.
Architektur atomarer Deployments mit symbolischen Links
Ein Ausrollen von Änderungen über git pull direkt im Hauptverzeichnis oder manuelle FTP-Uploads erzeugen einen instabilen Zwischenzustand. Während Dateien übertragen werden, greifen Besucher möglicherweise auf neue PHP-Klassen zu, während aufgerufene Hilfsfunktionen in noch unvollständigen Dateien fehlen. Das führt zu fatalen Fehlern im Produktivbetrieb.
Verzeichnisstruktur nach Vorbild von Deployer und Capistrano
Atomare Deployments trennen Releases, gemeinsame Verzeichnisse und den aktiven Symlink:
/var/www/meineseite/
├── current -> /var/www/meineseite/releases/20261012120000/
├── releases/
│ ├── 20261012100000/
│ ├── 20261012110000/
│ └── 20261012120000/
└── shared/
├── .env
└── wp-content/
└── uploads/Atomares Umschalten des Symlinks
- Jedes Release wird in einem neuen Unterordner von
releases/mit einem Zeitstempel abgelegt. - Es werden symbolische Links auf geteilte Ressourcen im Verzeichnis
shared/erstellt (wie Medien-Uploads und.env). - Abhängigkeiten werden installiert, Skripte kompiliert und Überprüfungen durchgeführt.
- Erst nach erfolgreichem Abschluss aller Schritte wird der Symlink
currentin einer einzigen atomaren Dateisystemoperation umgeschaltet:
ln -sfn /var/www/meineseite/releases/20261012120000 /var/www/meineseite/current_temp && mv -Tf /var/www/meineseite/current_temp /var/www/meineseite/currentDer Systemaufruf rename() auf Linux-Ebene arbeitet atomar. Für den Webserver Nginx oder Apache erfolgt der Versionswechsel in Mikrosekunden. Schlägt die Installation oder der Build fehl, bleibt der bestehende Release-Ordner unberührt und die Website läuft ohne Ausfallzeit weiter.
Sofortiger Rollback im Fehlerfall
Sollte nach dem Release ein unerwarteter Fehler auftreten, ist keine Wiederherstellung aus einem langsamen Backup erforderlich. Es genügt, den Symlink auf den vorherigen Release-Ordner zurückzustellen und den Cache zu leeren:
ln -sfn /var/www/meineseite/releases/20261012110000 /var/www/meineseite/current
wp cache flush
sudo systemctl reload php8.3-fpmAutomatisierung mit Bare-Repositories und post-receive Hooks
Für Setups ohne externe CI-Plattformen lässt sich ein nativer Push-to-Deploy-Workflow direkt mit Git auf dem Linux-Server über ein Bare-Repository und einen post-receive-Hook einrichten.
Erstellen des Bare-Repositories auf dem Server
mkdir -p /var/repo/meineseite.git
cd /var/repo/meineseite.git
git init --bareKonfigurieren des post-receive Hooks
Erstellen Sie die Datei /var/repo/meineseite.git/hooks/post-receive:
#!/bin/bash
TARGET_DIR="/var/www/meineseite/releases/$(date +%Y%m%d%H%M%S)"
SHARED_DIR="/var/www/meineseite/shared"
CURRENT_LINK="/var/www/meineseite/current"
echo "===> Starte WordPress-Deployment..."
mkdir -p "$TARGET_DIR"
# Quellcode aus dem Hauptzweig auschecken
git --work-tree="$TARGET_DIR" --git-dir=/var/repo/meineseite.git checkout -f main
# Geteilte Ressourcen verlinken
ln -s "$SHARED_DIR/.env" "$TARGET_DIR/.env"
rm -rf "$TARGET_DIR/wp-content/uploads"
ln -s "$SHARED_DIR/wp-content/uploads" "$TARGET_DIR/wp-content/uploads"
# Composer-Abhängigkeiten installieren
if [ -f "$TARGET_DIR/composer.json" ]; then
cd "$TARGET_DIR" && composer install --no-dev --optimize-autoloader --quiet
fi
# Datenbank-Schema bei Bedarf aktualisieren
wp core update-db --path="$TARGET_DIR" --quiet
# Symlink atomar umschalten
ln -sfn "$TARGET_DIR" "${CURRENT_LINK}_temp" && mv -Tf "${CURRENT_LINK}_temp" "$CURRENT_LINK"
# Objekt-Cache leeren und PHP-FPM neu laden
wp cache flush --path="$CURRENT_LINK" --quiet
sudo systemctl reload php8.3-fpm
echo "===> Deployment ohne Ausfallzeit abgeschlossen."Machen Sie das Skript ausführbar:
chmod +x /var/repo/meineseite.git/hooks/post-receiveFügen Sie den Server lokal als zusätzliches Git-Remote-Ziel hinzu:
git remote add production deploy@server:/var/repo/meineseite.git
git push production mainBei jedem Push überträgt Git die Deltas verschlüsselt über SSH, der Server baut das Release im Zielordner auf und aktiviert es unterbrechungsfrei.
Server-Härtung nach dem Deployment
Ein moderner Deployment-Prozess muss durch eine konsequente Absicherung der Server-Infrastruktur ergänzt werden.
Deaktivieren von XML-RPC
Die XML-RPC-Schnittstelle ist ein veraltetes Protokoll, das regelmäßig für Brute-Force-Angriffe und DDoS-Verstärkungsangriffe missbraucht wird. Sofern keine mobilen Apps oder Jetpack darauf angewiesen sind, deaktivieren Sie die Schnittstelle über ein mu-plugin:
add_filter( 'xmlrpc_enabled', '__return_false' );In Nginx kann der Zugriff zusätzlich auf Serverebene gesperrt werden:
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}Korrekte Dateiberechtigungen im Linux-Dateisystem
Der Webserver-Benutzer (www-data) darf niemals Eigentümer der Programmdateien sein. Der Deployment-Benutzer besitzt die Dateien, während der Webserver nur Leserechte für PHP-Skripte und Schreibrechte für das Verzeichnis uploads erhält:
# Standardberechtigungen für Dateien und Verzeichnisse
find /var/www/meineseite/current -type f -exec chmod 644 {} \;
find /var/www/meineseite/current -type d -exec chmod 755 {} \;
# Strikte Rechte für Konfigurationsdateien mit Zugangsdaten
chmod 600 /var/www/meineseite/shared/.env
# Schreibrechte für Medien-Uploads für den Webserver
chown -R deploy:www-data /var/www/meineseite/shared/wp-content/uploads
chmod -R 775 /var/www/meineseite/shared/wp-content/uploadsBrute-Force-Schutz mit fail2ban
Installieren und aktivieren Sie fail2ban, um IP-Adressen nach wiederholten fehlgeschlagenen SSH-Logins automatisch zu sperren:
sudo apt update && sudo apt install fail2ban -y
sudo systemctl enable --now fail2banKonfigurieren Sie /etc/fail2ban/jail.local mit restriktiven Parametern:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 1h
findtime = 10mWarum git pull im Produktivverzeichnis riskant ist
Viele Entwickler, die von FTP auf Git umsteigen, führen zunächst git pull origin main direkt im Hauptordner des Webservers aus. Dies bringt zwar Versionskontrolle, birgt jedoch erhebliche Gefahren für Produktionsumgebungen:
- Unvollständige Ladezustände: Während Git Dateien über das Netzwerk aktualisiert, werden PHP-Dateien zeitlich versetzt ausgetauscht. Greift ein Besucher genau in diesem Moment auf eine Seite zu, können Funktionsaufrufe ins Leere laufen und HTTP-500-Fehler erzeugen.
- Merge-Konflikte bei Dateimodifikationen: Werden auf dem Server Dateien verändert (etwa durch automatische Übersetzungen oder Sicherheits-Plugins), bricht das nächste
git pullmit einem Konflikt ab. Das Deployment bleibt unvollständig stehen. - Sicherheitslücke durch offenes .git-Verzeichnis: Liegt das Repository direkt im öffentlich zugänglichen Webroot, kann ein unzureichend konfigurierter Webserver dazu führen, dass Angreifer sensible Metadaten aus
.git/herunterladen und den Quellcode rekonstruieren.
Verifizierung und automatisierte Tests nach dem Release
Ein Deployment ist erst dann abgeschlossen, wenn die Funktionsfähigkeit des Gesamtsystems überprüft wurde:
- HTTP-Statusprüfungen: Automatische Tests mit
curlverifizieren, dass Startseite, API-Endpunkte und Unterseiten Status 200 liefern. - Logfile-Analyse: Die Überwachung von
debug.logund den PHP-FPM-Fehlerprotokollen unmittelbar nach dem Release deckt versteckte Warnungen und Inkompatibilitäten frühzeitig auf. - Transaktionsprüfung: Bei E-Commerce-Systemen mit WooCommerce werden Checkout-Routen und Warenkorb-Aufrufe verifiziert.
Sichere Verwaltung von Zugangsdaten im Git-Workflow
Mit der Einführung von Git ändern sich die Anforderungen an das Geheimnismanagement:
- Private SSH-Schlüssel verbleiben lokal: Sie werden niemals auf fremde Server oder in Repositories kopiert.
- Pipeline-Schlüssel erhalten minimale Rechte: Für CI/CD-Systeme wie GitHub Actions werden separate Deploy-Keys angelegt.
- Datenbank-Passwörter gehören in .env-Dateien: Sie werden niemals in Git versioniert. Wurde ein Kennwort versehentlich eingecheckt, reicht das Löschen der Datei im Folgecommit nicht aus; das Passwort muss umgehend geändert werden, da es dauerhaft in der Git-Historie verbleibt.
Checkliste für die Migration von FTP zu Git und SSH
Phase 1: Fundament
- ED25519-SSH-Schlüssel für alle Entwickler im Team erstellen.
- Passwort-Authentifizierung in
/etc/ssh/sshd_configdeaktivieren (PasswordAuthentication no). - WP-CLI auf allen Zielservern installieren.
- Aliase in
~/.ssh/configeinrichten.
Phase 2: Versionskontrolle
- Git im Projekt initialisieren und eine strikte
.gitignoreanlegen. - Plugins und Themes nach Möglichkeit auf Composer umstellen.
- Klare Branching-Strategie mit
mainund Feature-Branches festlegen.
- Git im Projekt initialisieren und eine strikte
Phase 3: Automatisiertes Deployment
- Staging-Umgebung mit Parität zur Produktion einrichten.
- Deployment-Skripte mit rsync oder Deployer aufsetzen.
- GitHub Actions oder
post-receive-Hooks auf dem Server konfigurieren.
Phase 4: Härtung und Betrieb
- Zugangsdaten vollständig in
.env-Dateien auslagern. - Dateiberechtigungen setzen (644 für Dateien, 755 für Verzeichnisse, 600 für Konfigurationen).
-
fail2baninstallieren und XML-RPC abschalten. - Rollback-Prozess für Notfälle testen.
- Zugangsdaten vollständig in
Technisches Fazit für modernes WordPress-Deployment
“Fehler 29” ist kein unvermeidlicher Bug, sondern ein klares Zeichen dafür, veraltete FTP-Verfahren hinter sich zu lassen.
- Ersetzen Sie FTP durch SFTP für gelegentliche manuelle Eingriffe.
- Nutzen Sie ED25519-SSH-Keys für den sicheren Serverzugriff ohne Passwörter.
- Automatisieren Sie Releases über Git und rsync mit sauberen Ausschlussmustern.
- Setzen Sie auf atomare Deployments mit Symlinks, um Ausfallzeiten zu eliminieren und sekundenschnelle Rollbacks zu ermöglichen.
Diese Infrastruktur spart Entwicklungszeit und schützt den laufenden Betrieb Ihrer Kundenprojekte. Erfahren Sie mehr über professionelle WordPress-Entwicklung und moderne Workflows bei WPPoland.







