Vollautomatisiertes WordPress- und WooCommerce-Hosting auf Ubuntu 24.04 LTS mit Proxmox. Ein Satz Bash-Scripts richtet die komplette Infrastruktur ein und legt produktionsfertige Sites in Minuten an. Jede Site bekommt einen eigenen PHP-FPM-Pool, Systemuser, Datenbank, SFTP-Zugang und Filebrowser-User — sauber voneinander isoliert.
Was es kann (Kurzfassung):
- 🚀 Eine VM-Vorlage, beliebig viele VMs — Cloud-init-Template + Klon-Script für Proxmox
- 🌐 Multi-Tenant-Web-Stack — Nginx + FastCGI-Cache, PHP 8.3-FPM (pro Site eigener Pool), Redis Object Cache
- 🛍️ WooCommerce-DE-ready — rechtliche Seiten, Widerrufsrecht-Checkbox (§356/§312j BGB), 4 Payment-Gateways, PDF-Rechnungen
- 📊 Tracking lean & DSGVO-konform — Matomo (cookieless) + Pixel Manager (alle Ad-Plattformen + CAPI) + FAZ Consent. Kein GA4/GTM.
- 🔒 Härtung out-of-the-box — fail2ban, Rate-Limits, 2FA, Chroot-SFTP, Vhost-Hardening
- 💾 Backups + Monitoring — täglich Files & DB, 7-Tage-Mirror nach R2/S3/SFTP (optional age-verschlüsselt), Backup-Verify, Disk-/SSL-Alerts
- 🛠️ MainWP-Dashboard — eigene VM-Vorlage für zentrale Update-Verwaltung aller Child-Sites
- 🔁 Reproduzierbar — config-getriebener, non-interaktiver Modus für Ansible/Automation
- Architektur
- Scripts
- Komplette Einrichtung — Schritt für Schritt
- MainWP Dashboard auf eigener VM (optional)
- Was wird pro Site installiert
- Monitoring & Alerts
- Backup
- Zugangsdaten
- SFTP-Zugang pro Site
- Maintenance Mode
- Voraussetzungen
- Lizenz & Haftungsausschluss
Internet → Cloudflare → Nginx Proxy Manager (SSL + Authentik-OIDC für MainWP)
↓ HTTP intern
┌──────────────────┬──────────────────┬──────────────────┐
Web-VM 1 Web-VM 2 MainWP-VM
(WordPress) (WooCommerce) (Dashboard, Admin-only)
Nginx + FastCGI Nginx + FastCGI Nginx (kein Cache)
PHP 8.3-FPM 256M PHP 8.3-FPM 512M PHP 8.3-FPM 1536M
Redis 256mb Redis 512mb Redis 1024mb
phpMyAdmin :8080 phpMyAdmin :8080 phpMyAdmin :8080
Filebrowser :8090 Filebrowser :8090 Filebrowser :8090
Netdata :19999 Netdata :19999 Netdata :19999
└──────────────────┴──────────────────┴──────────────────┘
↓
Datenbank-VM (gemeinsam)
MariaDB
Netdata :19999
| Script | Ausführen auf | Zweck | Wann |
|---|---|---|---|
proxmox-create-template.sh |
Proxmox Host | Ubuntu 24.04 Cloud-init Template erstellen | Einmalig |
proxmox-create-vm.sh |
Proxmox Host | VM aus Template klonen & konfigurieren | Pro neue VM |
setup-db.sh |
Datenbank-VM | MariaDB, Backups, Monitoring, SSH-Hardening | Einmalig pro VM |
setup-web.sh |
Web-VM | Nginx, PHP, Redis, Tools, Monitoring, Backups | Einmalig pro VM |
install-wp.sh |
Web-VM | Neue WordPress- oder WooCommerce-Site anlegen | Pro neue Site |
delete-wp.sh |
Web-VM | Site vollständig entfernen | Bei Bedarf |
maintenance.sh |
Web-VM | Maintenance Mode ein-/ausschalten | Bei Bedarf |
update-wp.sh |
Web-VM | Manuelles CLI-Update einzelner Sites (mit Pre-Update-Snapshots) — Updates laufen primär über MainWP | Fallback |
list-sites.sh |
Web-VM | Alle Sites mit Status anzeigen | Bei Bedarf |
clone-site.sh |
Web-VM | Bestehende Site auf neue Domain klonen | Bei Bedarf |
migrate-wp.sh |
Web-VM | Externe WordPress-Site importieren | Bei Bedarf |
health-check.sh |
Web-VM | HTTP, PHP-FPM, DB aller Sites prüfen | Bei Bedarf |
reset-wp-admin.sh |
Web-VM | WordPress-Admin-Passwort zurücksetzen | Bei Bedarf |
rotate-keys.sh |
Web-VM | WordPress Security Keys rotieren | Alle 3–6 Monate |
restore-wp.sh |
Web-VM | WordPress-Site aus Backup wiederherstellen (mit HTTP-Test + Auto-Rollback) | Bei Bedarf |
backup-verify.sh |
Web-VM | Backup-Integrität prüfen (tar + age-Decrypt) | Wöchentlich (Cron) |
status.sh |
Web-VM | Dashboard: Sites, Disk, Load, SSL, Updates, Backups | Bei Bedarf |
tail-logs.sh |
Web-VM | Live-Logs einer Site (Nginx + PHP, farblich getrennt) | Bei Bedarf |
audit-plugins.sh |
Web-VM | Plugin-/Site-Audit: veraltete/inaktive Plugins, Admin-User, DB-Bloat | Monatlich |
sync-plugins.sh |
Web-VM | Private Plugin-ZIPs (SEOpress Pro etc.) aus Plugin-Bucket nachladen | Bei Plugin-Update |
db-backup.sh |
Datenbank-VM | Manueller MariaDB-Dump (Encryption + Remote-Mirror wie Auto-Cron, flock-protected) | Bei Bedarf |
db-cleanup.sh |
Web-VM | DB-Cleanup aller Sites: Transients, Papierkorb, Spam, Action Scheduler, OPTIMIZE TABLE | Wöchentlich (Cron So 05:00) |
check-dns.sh |
beliebig | DNS-/Mail-Readiness prüfen (A, www, SPF, DMARC, SES-DKIM) — eine oder mehrere Domains | Vor Anlage |
📥 Scripts laden — zwei Wege. Das Repo ist öffentlich, also ist kein Token/Login nötig.
Variante A — ganzes Repo klonen (empfohlen). Auf jeder Maschine (Proxmox-Host, DB-VM, Web-VMs) einmal klonen, dann das jeweils benötigte Script ausführen:
git clone https://github.com/djanzin/wp-hosting-scripts.git cd wp-hosting-scriptsVariante B — einzelnes Script per
curl. Wenngitnicht installiert ist, lädst du nur das Script, das du gerade brauchst (die Befehle in jedem Schritt unten sind genau dafür da):curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/<script>.sh
-fsSLbricht bei HTTP-Fehler laut ab (statt eine Fehlerseite zu speichern) und folgt Redirects. Tipp: nach dem Downloadhead -3 <script>prüfen — muss mit#!/bin/bashbeginnen.
curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/proxmox-create-template.sh
bash proxmox-create-template.shErstellt ein Ubuntu 24.04 Cloud-init Template (Standard-ID: 9000).
curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/proxmox-create-vm.sh
bash proxmox-create-vm.sh # Datenbank-VM
bash proxmox-create-vm.sh # WordPress-VM
bash proxmox-create-vm.sh # WooCommerce-VMEmpfohlene Ressourcen:
| VM | vCPU | RAM | Disk |
|---|---|---|---|
| Datenbank | 4 | 8 GB | 50 GB |
| WordPress | 2 | 4 GB | 30 GB |
| WooCommerce | 4 | 8 GB | 40 GB |
| MainWP | 4 | 8 GB | 50 GB |
ssh ubuntu@<DB-VM-IP>
curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/setup-db.sh
sudo bash setup-db.shGibt DB-Admin-Zugangsdaten aus → für Schritt 4 notieren.
ssh ubuntu@<WEB-VM-IP>
curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/setup-web.sh
sudo bash setup-web.shFragt nach: VM-Typ, DB-VM-IP, DB-Zugangsdaten, Admin-E-Mail, NPM-IP, Webhook-URL, SEOpress-Key, Remote-Backup-Ziel.
Reproduzierbar/non-interaktiv:
setup-web.conf.examplekopieren, ausfüllen, dannsudo bash setup-web.sh --config setup-web.conf. Alle gesetzten Werte werden nicht mehr abgefragt — ideal für mehrere identische Web-VMs.
Tipp: DNS/Mail vorab prüfen mit
bash check-dns.sh <domain> --ip <ip> --dkim <ses-token>(siehedocs/dns-mail-setup.md) — dann läuft der Pre-Flight-Check glatt durch.
curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/install-wp.sh
sudo bash install-wp.shFragt nach Domain und Typ (WordPress oder WooCommerce).
Danach NPM Proxy-Host anlegen: https://domain.de → http://<WEB-VM-IP>:80
SEOpress Pro: Lade die ZIP einmal nach
r2:wp-plugins/seopress-pro.ziphoch (oder welcher Plugin-Bucket bei Setup angegeben wurde). Beim erstensetup-web.sh-Lauf wird sie automatisch nach/etc/wp-hosting/plugins/synchronisiert. Spätere Updates: ZIP in R2 ersetzen, dannsudo bash sync-plugins.sh.
Tipp: Bei abgebrochener Installation (z.B. Netzwerkfehler beim Plugin-Download) kann mit
sudo bash install-wp.sh --resumeein sauberer Neustart erzwungen werden — Reste der vorherigen Installation werden vor dem Neuversuch automatisch entfernt.
Non-Interactive (für Automation/Ansible):
sudo bash install-wp.sh --domain example.com --type wordpress --yes sudo bash install-wp.sh --domain shop.de --type woocommerce --shop-name "Mein Shop" --admin-ip 1.2.3.4 --yes
Jede neue Site startet im Maintenance Mode:
curl -fsSLO https://raw.githubusercontent.com/djanzin/wp-hosting-scripts/main/maintenance.sh
sudo bash maintenance.sh→ Domain auswählen → freischalten → Site ist live.
Für die zentrale Verwaltung aller Child-Sites lohnt sich eine eigene MainWP-VM als 4. Web-VM. Vorteile gegenüber Co-Hosting auf einer WordPress-VM:
- 1536M PHP-Memory für Sync mit vielen Child-Sites
- Reduzierter Plugin-Stack (keine SEO/Cookie/Antispam-Plugins für eine reine Admin-Site)
- Eigene Auth-Schicht via NPMPlus Forward-Auth zu Authentik (kein public-erreichbares wp-login)
# 1) Proxmox Host — VM anlegen mit Option 4 (MainWP, 4/8/50)
bash proxmox-create-vm.sh
# 2) Auf der neuen VM — Web-Stack mit Option 3 (MainWP Dashboard)
sudo bash setup-web.sh
# 3) Dashboard-Site (genau eine — Single-Site-by-design)
sudo bash install-wp.sh --domain mainwp.example.com --type mainwp --yesmainwp-dashboard.zip— wird auf der mainwp-VM auto-installiertmainwp-child.zip— auf jeder normalen WP-/Woo-Site auto-installiert (Standard)
Nach Upload neuer ZIP-Versionen: sudo bash sync-plugins.sh --plugins
In NPMPlus für die MainWP-Domain einen Proxy-Host anlegen:
- Domain:
mainwp.example.com - Forward zu:
http://<MainWP-VM-IP>:80 - SSL: Let's Encrypt aktivieren
- Advanced → Custom Nginx Configuration (Snippet aus Authentik Outpost-Doku):
# Pass auth requests to Authentik Outpost
location /outpost.goauthentik.io {
proxy_pass http://<authentik-outpost-ip>:9000/outpost.goauthentik.io;
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
add_header Set-Cookie $auth_cookie;
auth_request_set $auth_cookie $upstream_http_set_cookie;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
# Forward-Auth für alle Requests
auth_request /outpost.goauthentik.io/auth/nginx;
error_page 401 = @goauthentik_proxy_signin;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
auth_request_set $authentik_username $upstream_http_x_authentik_username;
proxy_set_header X-authentik-username $authentik_username;
location @goauthentik_proxy_signin {
internal;
add_header Set-Cookie $auth_cookie;
return 302 /outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}In Authentik:
- Proxy-Provider für die MainWP-Domain anlegen (Forward-Auth Mode)
- Einer Application zuweisen
- Im Outpost veröffentlichen
Reduzierter Plugin-Stack (5 Plugins, keine Front-End-Plugins):
| Plugin | Zweck |
|---|---|
| MainWP Dashboard | Zentrale Verwaltung der Child-Sites |
| Two Factor | 2FA — zusätzliche Schicht hinter Authentik |
| Redis Object Cache | Performance |
| FluentSMTP | E-Mail-Notifications |
| Nginx Helper | (Purge deaktiviert — kein FastCGI-Cache auf mainwp-Vhost) |
Kein Blocksy, kein WooCommerce, kein MainWP Child auf der Dashboard-Site selbst.
- Eigener Systemuser (
wp_domain_com) — PHP-FPM läuft unter diesem User - Eigener PHP-FPM-Pool (dynamic für WP, static für WooCommerce, Slow Log ab 5s)
- Eigener Nginx-Vhost mit FastCGI-Cache und WebP-Serving
- Eigene MariaDB-Datenbank + User mit 32-stelligem Passwort
- WP-Cron via System-Cron (alle 5 Minuten, kein Frontend-Overhead)
- SFTP-Zugang (Chroot-Jail, Passwort-Auth, landet direkt im Site-Verzeichnis)
- Filebrowser-User mit Scope auf das Site-Verzeichnis
- Sprache:
en_US, Zeitzone:Europe/Berlin, Datum:Y-m-d H:i - Permalinks:
/%category%/%postname%/ - Admin-Profil: Danijel Janzin, Spitzname Dany
- Vhost-Härtung:
xmlrpc.php,wp-config.php,readme.html, PHP in/uploads/blockiert - Rate-Limit:
wp-login.php1 r/s, Burst 3 (verhindert Brute-Force) - fail2ban-Jails: wp-login Brute-Force (5 Versuche → 2h Ban), xmlrpc (2 Hits → 24h Ban)
- OPcache-Status:
https://<domain>/opcache-status(Basic-Auth, gleiches Passwort wie phpMyAdmin) - PHP-FPM Pool-Status:
https://<domain>/fpm-status(Basic-Auth) zeigt aktive/idle Worker, Queue-Tiefe, peak children DISALLOW_FILE_EDIT,FORCE_SSL_ADMIN,WP_DEBUG falseWP_MEMORY_LIMIT 256M/WP_MAX_MEMORY_LIMIT 512MWP_POST_REVISIONS 5,EMPTY_TRASH_DAYS 7,AUTOSAVE_INTERVAL 120WP_CACHE true(FastCGI + Redis Object Cache)- X-Forwarded-Proto-Fix für HTTPS hinter NPM
| Plugin | Zweck |
|---|---|
| Redis Object Cache | Object-Caching via Redis |
| Nginx Helper | FastCGI-Cache automatisch leeren |
| FluentSMTP | SMTP-E-Mail-Versand |
| Antispam Bee | Kommentar-Spam filtern |
| Simple Cloudflare Turnstile | Bot-Schutz für Formulare |
| WebP Converter for Media | Bilder bei Upload in WebP konvertieren |
| Two Factor | 2FA für WP-Admin |
| SEOpress + SEOpress Pro | SEO (Pro-ZIP + Lizenz-Key aus Config) |
| FAZ Cookie Manager | DSGVO-konformes Cookie Consent (GitHub) |
| Fluent Forms + Pro | Formulare (Free-Basis aus Repo + Pro-ZIP fluentformpro.zip aus Bucket) |
| MainWP Child | Remote-Verwaltung via zentralem MainWP Dashboard (mit auto-generierter Unique Security ID) |
DB-Cleanup statt WP-Optimize: Statt eines Plugins läuft
db-cleanup.shwöchentlich (So 05:00) per Cron über alle Sites — expired Transients, Papierkorb, Spam-Kommentare, Action-Scheduler-Cleanup (nur Woo-Shops),wp db optimize. Kein Frontend-Risiko, kein Cache-Konflikt.
- Plugins:
hello,akismetgelöscht - Themes:
twentytwentyonebistwentytwentyfourgelöscht - Inhalte: Hello-World-Post, Sample-Page, Standard-Kommentar gelöscht
- Dateien:
readme.html,license.txt,wp-config-sample.phpgelöscht - Pingbacks + Trackbacks deaktiviert
| Datei | Funktion |
|---|---|
server-cache.php |
Site-Health-Cache-Warnung unterdrücken |
performance.php |
Heartbeat drosseln, Admin-Bar ausblenden, Author-Enumeration blockieren |
maintenance-mode.php |
Maintenance Mode (Flag-Datei /wp-content/.maintenance-active) |
digital-checkout.php |
Widerrufsrecht-Checkbox bei WooCommerce (nur wenn downloadbare Produkte im Warenkorb) |
- Land: Deutschland, Währung: EUR
- Gastbestellung aktiviert, Checkout-Login-Erinnerung aktiviert
- Tracking, Marketplace-Vorschläge, Remote-Logging deaktiviert
- Rechtliche Seiten automatisch angelegt: Impressum, Datenschutzerklärung, AGB, Widerrufsbelehrung, Lieferung & Download
- AGB als Terms-Page, Datenschutz als Privacy-Page zugewiesen
- E-Mail-Absender: Shop-Name +
noreply@domain.de+ Footer mit Impressum-Link - Widerrufsrecht-Checkbox beim Checkout (§ 356 Abs. 5 BGB) — nur bei digitalen Produkten, server-seitig validiert, Zustimmung mit Zeitstempel in Bestellung gespeichert
- Button-Lösung (§ 312j Abs. 3 BGB): Bestell-Button = „Zahlungspflichtig bestellen" (via
digital-checkout.php, anpassbar) - AGB-Checkbox am Checkout automatisch (WooCommerce zeigt sie, da AGB als Terms-Page gesetzt)
- Kein WooCommerce Germanized — Rechtskonformität wird nativ + per mu-Plugin gelöst. (Grundpreise/PAngV bei Digital-Produkten nicht pflichtig.)
- Rechnungen via WowInvoice — auto-installiert aus
wowinvoice-pro.zip(Premium-only, kein wp.org-Free). PDF-Rechnungen + Packing Slips. - Payment Gateways automatisch installiert + aktiviert (API-Keys je Shop manuell): Mollie, PayPal Payments, Stripe, Amazon Pay
- FunnelKit Automations (Free-Basis + Pro-ZIP
funnelkit-automations-pro.zip) für E-Mail-Marketing (Warenkorbabbruch, Broadcasts) — ergänzt WowRevenue (On-Site-Funnels) - Produktfeeds + Tracking (Lean-Architektur) — ein Feed-Tool, ein Pixel-Tool:
- Product Feed Manager (
best-woocommerce-feed, Free) — erzeugt alle Kataloge/Feeds: Google (Content-API-Auto-Sync), Meta, TikTok, Pinterest, Bing Shopping, Idealo/Preisvergleiche. 24h-Schedule, Custom Fields, Varianten als Zeilen (Limit 200 Produkte/Feed → Pro-Lizenz manuell auf großen Shops) - Pixel Manager (
woocommerce-google-adwords-conversion-tracking-tag, Free +pixel-manager-pro.zip) — ein Pixel-Tool für alle Ad-Plattformen (Google Ads, Meta, TikTok, Pinterest, Bing) + Server-Side CAPI. Ersetzt Google Tag Manager. Consent-gated über FAZ. - Analytics = Matomo via SEOpress-Modul (cookieless, consent-frei). Kein GA4, kein GTM.
- Keine offiziellen Channel-Plugins (redundant durch PMW+PFM), kein buggy Pinterest-Plugin.
- Product Feed Manager (
📡 Tracking/Consent-Details + Pro-Shop-Checkliste: siehe
docs/tracking-consent.md
⚠️ Rechtliche Texte müssen manuell befüllt werden. Empfehlung: IT-Recht Kanzlei (Digital-Paket). 💳 Payment Gateways werden nur installiert — API-Keys/Modus konfigurierst du pro Shop in WooCommerce → Zahlungen. 📡 Feed-/Pixel-/Consent-Setup je Shop: im PFM-GUI je Plattform einen Feed anlegen (Template, Schedule „daily"); im Pixel Manager die Pixel-IDs + CAPI eintragen; in SEOpress Matomo aktivieren (cookieless); FAZ als einzige CMP (Consent Mode v2). Vollständige Schritt-für-Schritt-Checkliste:docs/tracking-consent.md.
| Alert | Trigger | Kanal |
|---|---|---|
| 🟡 Disk Warnung | Partition > 80% belegt | Webhook (stündlich) |
| 🔴 Disk Kritisch | Partition > 90% belegt | Webhook (stündlich) |
| 🟢 Disk OK | Partition wieder < 80% | Webhook (Recovery) |
| 🔴 SSL Fehler | Zertifikat läuft in < 2 Tagen ab (Erneuerung fehlgeschlagen) | Webhook (alle 6h) |
| 🟢 SSL OK | Zertifikat nach Fehler erfolgreich erneuert | Webhook (Recovery) |
| 🔴 Backup defekt | tar-Integrität oder age-Decrypt fehlgeschlagen | Webhook (sonntags 04:00) |
| fail2ban | wp-login Brute-Force, xmlrpc, PHP in Uploads | IP-Ban (1h–24h) |
Alle Alerts nutzen state-tracking — kein Spam, nur bei Zustandsänderung.
Webhook-Format: Uptime Kuma Push Monitor (GET ?status=up|down&msg=…).
- Täglich 02:00:
wp-content/als.tar.gznach/var/backups/wp-files/ - 7 Tage Aufbewahrung — lokal UND remote (rclone sync = Mirror, Remote spiegelt Lokal)
- Remote-Backup ist Pflicht (Cloudflare R2, S3 oder SFTP — Setup fragt ab)
- Bandbreiten-Limit: 8 MB/s tagsüber (08–22), unbegrenzt nachts
- Optional: age-Verschlüsselung vor Upload (
.tar.gz.age)
- Täglich 02:00: Pro Datenbank ein eigener komprimierter SQL-Dump nach
/var/backups/mysql/<dbname>_<datum>.sql.gz - 7 Tage Aufbewahrung — lokal UND remote (rclone sync = Mirror)
- Remote-Backup ist Pflicht (R2/S3/SFTP)
- Bandbreiten-Limit wie bei Files-Backup
- Optional: age-Verschlüsselung vor Upload (
.sql.gz.age) - Manuelle Backups (
db-backup.sh) verwenden denselben Code-Pfad: Encryption + Remote-Mirror identisch zum Auto-Cron,flock-Lock auf/var/lock/mysql-backup.lockverhindert parallele Läufe
Empfohlen: 3 Buckets in derselben R2/S3-Storage:
r2:wp-backups/ ← Backup-Bucket (7-Tage-Mirror)
├── wp-files-<web-vm-1-hostname>/
├── wp-files-<web-vm-2-hostname>/
└── mysql-backups-<db-vm-hostname>/
r2:wp-plugins/ ← private/Pro-Plugin-ZIPs
├── blocksy-companion-pro.zip
├── fluentformpro.zip ← Fluent Forms Pro (alle Sites)
├── funnelkit-automations-pro.zip ← E-Mail-Marketing (Woo)
├── pixel-manager-pro.zip ← alle Ad-Pixel + Server-Side CAPI (Woo)
├── mainwp-child.zip ← MainWP Child (auf JEDER Site auto-installiert)
├── mainwp-dashboard.zip ← MainWP Dashboard (nur auf mainwp-VM auto-installiert)
├── postxpro.zip ← Tech-Blog-Blocks
├── seopress-pro.zip
├── wowinvoice-pro.zip ← PDF-Rechnungen (Woo, Premium-only)
├── wowrevenue-pro.zip ← On-Site-Funnels (Woo)
└── wowstore-pro.zip ← Shop-Erweiterungen (Woo)
r2:wp-themes/ ← private/Pro-Theme-ZIPs
├── blocksy.zip ← Parent-Theme
└── blocksy-child.zip ← Child-Theme (für Anpassungen)
Warum 3 Buckets: Backups haben kurze Retention (7-Tage-Mirror), Plugin/Theme-ZIPs haben dauerhafte Aufbewahrung. Trennung erleichtert Lifecycle-Rules und verhindert versehentliches Löschen durch Backup-Sync.
Bei der Setup-Abfrage gibst du alle drei Bucket-Namen einmal ein. ZIPs werden beim Setup automatisch heruntergeladen:
- Plugins →
/etc/wp-hosting/plugins/ - Themes →
/etc/wp-hosting/themes/
Welche Plugins/Themes werden pro Site-Typ aktiviert:
| Plugin/Theme | Blog (wordpress) | Shop (woocommerce) | MainWP-Dashboard (mainwp) |
|---|---|---|---|
| Blocksy + Child Theme | ✓ | ✓ | — |
| Blocksy Companion Pro | ✓ | ✓ | — |
| SEOpress Pro | ✓ | ✓ | — |
| Redis Object Cache, FluentSMTP, Two Factor, Nginx Helper | ✓ | ✓ | ✓ |
| WebP Converter, Antispam Bee, Turnstile, FAZ Cookie Manager | ✓ | ✓ | — |
| Fluent Forms + Pro (Formulare) | ✓ | ✓ | — |
| MainWP Child (Remote-Verwaltung, Unique Security ID) | ✓ | ✓ | — |
| MainWP Dashboard (zentrale Verwaltung) | — | — | ✓ |
| PostX Pro (Reviews, Comparison, Query Loops) | ✓ | — | — |
| WowStore Pro (Shop-Erweiterung) | — | ✓ | — |
| WowRevenue Pro (On-Site-Funnels) | — | ✓ | — |
| WowInvoice (PDF-Rechnungen, Premium-only) | — | ✓ | — |
| FunnelKit Automations (E-Mail-Marketing) | — | ✓ | — |
| Payment Gateways (Mollie, PayPal, Stripe, Amazon Pay) | — | ✓ | — |
| Product Feed Manager (Free, alle Feeds: Google/Meta/TikTok/Pinterest/Bing/Idealo) | — | ✓ | — |
| Pixel Manager (Free + Pro-ZIP, alle Ad-Pixel + CAPI, ersetzt GTM) | — | ✓ | — |
| WooCommerce | — | ✓ | — |
Plugin-/Theme-Updates: Nach Upload einer neuen ZIP-Version in den jeweiligen Bucket:
sudo bash sync-plugins.sh # Plugins UND Themes synchronisieren
sudo bash sync-plugins.sh --plugins # nur Plugins
sudo bash sync-plugins.sh --themes # nur Themes
sudo bash sync-plugins.sh --list # Inventar (lokal + remote)Bestehende Sites müssen danach manuell mit wp plugin install ... --force aktualisiert werden.
- Wöchentlich (Sonntag 04:00):
backup-verify.shprüft tar-Integrität, age-Entschlüsselbarkeit und SQL-Inhalt - Webhook-Alert bei beschädigten Backups
- Alle Backup-Crons mit
flockgeschützt (kein paralleler Lauf bei langlaufenden Backups)
- Vor jedem WordPress-Update wird automatisch ein Schnell-Snapshot (Files + DB) angelegt
- Speicherort:
/var/backups/wp-pre-update/<domain>_<timestamp>.{tar.gz,sql.gz} - Retention: 5 letzte Snapshots pro Site
- Manueller Restore:
sudo bash restore-wp.sh→ SQL-/Tar-Datei aus diesem Verzeichnis wählen
| Datei | Inhalt |
|---|---|
/etc/wp-hosting/config |
VM-Typ, DB-Zugangsdaten, Webhook-URL, SEOpress-Key (Web-VM) |
/etc/wp-hosting/db-credentials.txt |
DB-Admin-Zugangsdaten (DB-VM) |
/etc/wp-hosting/db-backup.conf |
rclone-Remote-Ziel — geteilt von Auto-Cron + db-backup.sh (DB-VM) |
/etc/wp-hosting/sites/<domain>.txt |
WP-Admin, DB, Filebrowser, SFTP pro Site |
/etc/wp-hosting/deleted/<domain>.<datum>.txt |
Archivierte Zugangsdaten gelöschter Sites |
Host: <Web-VM-IP>
Port: 22
User: wp_domain_com
Passwort: <aus /etc/wp-hosting/sites/domain.txt>
Pfad: /site (entspricht /var/www/domain.com)
Chroot-Jail — kein Zugriff auf andere Sites möglich.
sudo bash maintenance.sh- Zeigt alle Sites mit Status
[LIVE]oder[MAINTENANCE] - Besucher sehen eine 503-Seite (dunkles Design, kein WordPress-Branding)
- Admins können sich einloggen und normal arbeiten
- Neue Sites starten automatisch im Maintenance Mode
- Proxmox VE 8.x
- Nginx Proxy Manager (SSL-Terminierung)
- Cloudflare (empfohlen, für Real-IP-Header)
- VMs können sich gegenseitig per IP erreichen
- Für Webhooks: Uptime Kuma Push Monitor URL (
https://…/api/push/<key>)
Veröffentlicht unter der MIT-Lizenz — siehe LICENSE. Nutzung auf eigene Verantwortung.
⚠️ Hinweis: Diese Scripts richten Server produktiv ein, ändern Firewall-/Nginx-/DB-Konfiguration und legen Cronjobs an. Vor dem Einsatz auf Produktivsystemen auf einer Wegwerf-VM testen. Die im Repo enthaltenen IPs (192.168.1.x) sind Platzhalter-Defaults und werden bei der Einrichtung abgefragt — keine echten Hosts. Pro/Premium-Plugin-ZIPs (SEOpress Pro, Blocksy Pro, Wow-Suite, Pixel Manager Pro etc.) sind nicht Teil des Repos; sie werden zur Laufzeit aus einem privaten Object-Storage-Bucket nachgeladen und erfordern eigene Lizenzen.