Self-Hosting von Windmill auf Ubuntu: Vollständiges Docker-Setup-Tutorial mit PostgreSQL-Fehlerbehebung
Workflow-Automatisierungsplattformen sind für moderne Entwicklungsteams unverzichtbar, aber Cloud-Lösungen wie Windmill Cloud können mit steigender Nutzung teuer werden. Wir zeigen Ihnen, wie Sie Ihre eigene Windmill-Instanz auf Ubuntu mit Docker Compose und Traefik-Integration einrichten und dabei kritische PostgreSQL-Authentifizierungsprobleme überwinden, die Ihre Installation zum Scheitern bringen können.
Was Sie aufbauen werden
Am Ende dieses Tutorials verfügen Sie über:
- Voll funktionsfähige Windmill-Installation mit HTTPS
- Automatische SSL-Zertifikate über Let's Encrypt durch Traefik
- Produktionsreife PostgreSQL-Datenbank mit korrekter Authentifizierung
- Ressourcenoptimierte Worker-Konfiguration
- Integration mit bestehender Docker-Infrastruktur
- Produktionsreifes Setup für professionelle Workflow-Automatisierung
Monatliche Kosten: 4,51 € (CX11-Server) + Domainkosten – dieselbe Infrastruktur kann mehrere Automatisierungstools betreiben
Voraussetzungen
- Ubuntu 24.04 LTS-Server mit installierten Docker und Docker Compose
- Bestehendes Traefik-Reverse-Proxy-Setup (siehe unseren n8n-Setup-Leitfaden für die Traefik-Konfiguration)
- Domainname, der auf Ihre Server-IP verweist
- Mindestens 4 GB RAM und 2 vCPUs empfohlen
- SSH-Zugang und grundlegende Kommandozeilenkenntnisse
Windmill verstehen
Windmill ist eine Open-Source-Workflow-Engine, die Folgendes bietet:
- Visueller Workflow-Editor mit TypeScript/Python/Go-Unterstützung
- Job-Scheduling und Ausführungsverwaltung
- API-Integrationsfähigkeiten
- Team-Kollaborationsfunktionen
- Self-Hostbar ohne Nutzungslimits
Im Gegensatz zum knotenbasierten Ansatz von n8n konzentriert sich Windmill auf Code-First-Workflows mit einer leistungsstarken Entwicklungsumgebung.
Schritt 1: Servervorbereitung und Verzeichnisstruktur
Zunächst bereiten wir unsere Serverumgebung vor. Wir verwenden eine lebensmittelbasierte Namenskonvention für Windmill-Instanzen, um Konflikte zu vermeiden:
# Create Windmill directory (first instance: "pizza")
mkdir -p /opt/windmill-pizza
cd /opt/windmill-pizza
# Create required subdirectories
mkdir -p postgres-data windmill-data lsp-cache
# Verify directory structure
ls -la
Namenskonvention: Verwenden Sie einfache Lebensmittelnamen für mehrere Windmill-Instanzen:
- Erste Instanz:
pizza - Weitere Instanzen:
pasta,salad,soup,burgerusw. - Dies vermeidet Konflikte und erleichtert die Verwaltung
Schritt 2: Umgebungskonfiguration
Erstellen Sie eine sichere Umgebungsdatei mit korrekten Zugangsdaten:
# Generate a secure hex password (no special characters!)
SECURE_PASSWORD=$(openssl rand -hex 16)
echo "Generated password: $SECURE_PASSWORD"
# Create environment file
cat > /opt/windmill-pizza/.env << EOF
# Windmill Image Version
WM_IMAGE=ghcr.io/windmill-labs/windmill:main
# Database Configuration - SECURE PASSWORDS
DATABASE_URL=postgresql://postgres:${SECURE_PASSWORD}@windmill-db:5432/windmill_pizza?sslmode=disable
POSTGRES_PASSWORD=${SECURE_PASSWORD}
POSTGRES_DB=windmill_pizza
POSTGRES_USER=postgres
# Windmill Configuration
BASE_URL=https://windmill.yourdomain.com
RUST_LOG=info
# Worker Configuration
WORKER_GROUP=default
KEEP_JOB_DIR=false
# Instance Identifier
INSTANCE_NAME=pizza
EOF
Wichtig: Ersetzen Sie windmill.yourdomain.com durch Ihre tatsächliche Domain!
Schritt 3: Docker-Compose-Konfiguration
Erstellen Sie die Haupt-Docker-Compose-Konfiguration:
cat > /opt/windmill-pizza/docker-compose.yml << 'EOF'
version: "3.8"
services:
# PostgreSQL Database for Windmill
windmill-db:
image: postgres:16
container_name: windmill-pizza-db
restart: unless-stopped
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- proxy
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Windmill Server
windmill-server:
image: ${WM_IMAGE}
container_name: windmill-pizza-server
restart: unless-stopped
environment:
- DATABASE_URL=${DATABASE_URL}
- BASE_URL=${BASE_URL}
- RUST_LOG=${RUST_LOG}
- MODE=server
networks:
- proxy
depends_on:
windmill-db:
condition: service_healthy
volumes:
- ./windmill-data:/tmp/windmill
labels:
- "traefik.enable=true"
- "traefik.http.routers.windmill-pizza.rule=Host(`windmill.yourdomain.com`)"
- "traefik.http.routers.windmill-pizza.entrypoints=https"
- "traefik.http.routers.windmill-pizza.tls.certresolver=letsencrypt"
- "traefik.http.services.windmill-pizza.loadbalancer.server.port=8000"
# Windmill Worker
windmill-worker:
image: ${WM_IMAGE}
container_name: windmill-pizza-worker
restart: unless-stopped
environment:
- DATABASE_URL=${DATABASE_URL}
- BASE_URL=${BASE_URL}
- RUST_LOG=${RUST_LOG}
- MODE=worker
- WORKER_GROUP=${WORKER_GROUP}
- KEEP_JOB_DIR=${KEEP_JOB_DIR}
networks:
- proxy
depends_on:
windmill-db:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./windmill-data:/tmp/windmill
- worker_dependency_cache:/tmp/windmill/cache
deploy:
resources:
limits:
cpus: '1'
memory: 2G
networks:
proxy:
external: true
volumes:
worker_dependency_cache:
driver: local
EOF
Wichtig: Aktualisieren Sie die Domain in den Traefik-Labels entsprechend Ihrem Setup!
Schritt 4: Das PostgreSQL-Passwort-Problem (Kritisches Problem)
Hier scheitern die meisten Windmill-Installationen, und es erforderte erhebliche Fehlersuche, um die Ursache zu identifizieren:
Das Problem: Sonderzeichen in Passwörtern
Bei der Verwendung von openssl rand -base64 32 zur Passwortgenerierung erhalten Sie oft Sonderzeichen wie =, @, #, % usw. Diese Zeichen verursachen PostgreSQL-Authentifizierungsfehler in Docker-Umgebungen, selbst wenn sie korrekt maskiert sind.
Beispiel eines problematischen Passworts:
# This WILL cause authentication failures:
PASSWORD="305t6m9KrChkvbyNEFLEYQ6pqAGlApn9rbJPH3D5y9g="
Die Lösung: Reine Hex-Passwörter
Verwenden Sie reine Hex-Passwörter, die keine Sonderzeichen enthalten:
# This WORKS reliably:
PASSWORD=$(openssl rand -hex 16)
# Example result: 5781b14ec0ec1bc184653ffa5e379411
Zusätzliche PostgreSQL-Konfigurationsprobleme
- Benutzerkonfiguration: Verwenden Sie
postgresals Standardbenutzer, nicht benutzerdefinierte Benutzer wiewindmill_user - Volume-Persistenz: PostgreSQL ignoriert
POSTGRES_PASSWORD-Umgebungsvariablen, wenn bestehende Datenvolumes andere Zugangsdaten enthalten - URL-Format: Fügen Sie
?sslmode=disablein die Datenbank-URL für Docker-Umgebungen ein
Schritt 5: Installation und Start
Installieren wir nun Windmill mit unserer korrigierten Konfiguration:
cd /opt/windmill-pizza
# Verify configuration syntax
docker compose config --quiet
# Pull images
docker compose pull
# Start services
docker compose up -d
# Check status
docker compose ps
Sie sollten eine Ausgabe wie diese sehen:
NAME STATUS PORTS
windmill-pizza-db Up (healthy) 5432/tcp
windmill-pizza-server Up 8000/tcp
windmill-pizza-worker Up 8000/tcp
Schritt 6: Fehlerbehebung häufiger Probleme
Problem 1: PostgreSQL-Authentifizierungsfehler
Symptome:
windmill-pizza-server | Error: password authentication failed for user "postgres"
Lösung:
# Stop containers
docker compose down --volumes
# Remove old data
rm -rf postgres-data/*
# Regenerate hex password
NEW_PASSWORD=$(openssl rand -hex 16)
sed -i "s/POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$NEW_PASSWORD/" .env
sed -i "s/:.*@/:$NEW_PASSWORD@/" .env
# Restart
docker compose up -d
Problem 2: Container startet nicht
Symptome:
- Container beendet sich sofort
- Ressourcenzuweisungsfehler
Lösung:
# Check container logs
docker logs windmill-pizza-server
docker logs windmill-pizza-db
# Check system resources
docker stats
free -h
Problem 3: SSL-Zertifikatsprobleme
Symptome:
- HTTPS funktioniert nicht
- Zertifikatsfehler
Lösung:
# Check Traefik logs
docker logs traefik
# Verify DNS resolution
nslookup windmill.yourdomain.com
# Restart Traefik if needed
docker restart traefik
Schritt 7: Zugang und Ersteinrichtung
Nach Abschluss der Installation:
- Windmill aufrufen: https://windmill.yourdomain.com
- Standard-Zugangsdaten:
- E-Mail:
admin@windmill.dev - Passwort:
changeme
- E-Mail:
- Einrichtung abschließen:
- Admin-Passwort ändern
- Basis-URL konfigurieren
- Benutzerkonten einrichten
Schritt 8: Ressourcenoptimierung
Speicherzuweisung (für 8-GB-Server)
Unsere Konfiguration weist Ressourcen effizient zu:
- Windmill Server: ~800 MB
- Windmill Worker: 2 GB (begrenzt)
- PostgreSQL: ~500 MB
- Systemreserve: ~4,7 GB
CPU-Zuweisung (für 4-vCPU-Server)
- Worker: 1 vCPU (begrenzt)
- Andere Dienste: 3 vCPUs (geteilt)
Skalierungsregel: 1 Worker pro vCPU mit jeweils 1–2 GB RAM
Schritt 9: Produktionshärtung
Backup-Skript erstellen
cat > /opt/windmill-pizza/backup.sh << 'EOF'
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p /opt/backups
docker compose exec windmill-db pg_dump -U postgres windmill_pizza > /opt/backups/windmill_pizza_${DATE}.sql
echo "Backup created: windmill_pizza_${DATE}.sql"
EOF
chmod +x /opt/windmill-pizza/backup.sh
Monitoring einrichten
# Monitor container health
docker compose ps
# Check resource usage
docker stats
# Monitor logs
docker compose logs -f windmill-server
Automatisierte Updates konfigurieren
cat > /opt/windmill-pizza/update.sh << 'EOF'
#!/bin/bash
cd /opt/windmill-pizza
docker compose pull
docker compose up -d --force-recreate
EOF
chmod +x /opt/windmill-pizza/update.sh
Schritt 10: Erweiterte Konfiguration
Integration mit bestehendem SMTP
Wenn Sie einen Mailserver haben (z. B. aus unserem n8n-Setup), integrieren Sie ihn:
# Add to docker-compose.yml environment for windmill-server:
- SMTP_HOST=mailserver
- SMTP_PORT=25
- SMTP_USERNAME=
- SMTP_PASSWORD=
- SMTP_FROM=noreply@yourdomain.com
Mehrere Windmill-Instanzen
Für Teams, die isolierte Umgebungen benötigen:
# Create second instance
cp -r /opt/windmill-pizza /opt/windmill-pasta
# Update configuration
sed -i 's/pizza/pasta/g' /opt/windmill-pasta/.env
sed -i 's/windmill.yourdomain.com/pasta.yourdomain.com/g' /opt/windmill-pasta/.env
# Generate new password
NEW_PASSWORD=$(openssl rand -hex 16)
sed -i "s/POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$NEW_PASSWORD/" /opt/windmill-pasta/.env
# Update docker-compose.yml
sed -i 's/pizza/pasta/g' /opt/windmill-pasta/docker-compose.yml
sed -i 's/windmill.yourdomain.com/pasta.yourdomain.com/g' /opt/windmill-pasta/docker-compose.yml
Sicherheitsaspekte
Netzwerkisolierung
- PostgreSQL nur innerhalb des Docker-Netzwerks erreichbar
- Keine externen Datenbankports freigegeben
- HTTPS-Terminierung auf Traefik-Ebene
Ressourcenlimits
- Worker-Container haben CPU- und Speicherlimits
- Verhindert Ressourcenerschöpfungsangriffe
- Konfigurierbar basierend auf Serverkapazität
SSL-Sicherheit
- Automatische Let's-Encrypt-Zertifikate
- HTTP-zu-HTTPS-Weiterleitungen
- Moderne TLS-Konfiguration
Überwachung und Wartung
Wöchentliche Gesundheitschecks
# Container status
docker compose ps
# Resource usage
docker stats --no-stream
# Log analysis
docker compose logs | grep -i error
Monatliche Wartung
# Update containers
cd /opt/windmill-pizza
./update.sh
# Clean old data
docker system prune -f
# Backup database
./backup.sh
Kostenaufstellung und Vergleich
Monatliche Kosten
Self-Hosted-Setup:
- Hetzner CX21 (4 GB RAM): 8,46 €/Monat
- Domainkosten: ~1 €/Monat
- Gesamt: ~9,50 €/Monat
Windmill Cloud im Vergleich:
- Team-Plan: 30 $/Monat pro Benutzer
- Einsparungen: 250 $+ jährlich für kleine Teams
Leistungsvorteile
Vorteile des Self-Hosting:
- Unbegrenzte Workflow-Ausführungen
- Keine externen Rate-Limits
- Volle Datenkontrolle
- Individuelle Integrationen
- Flexible Ressourcenskalierung
Fehlerbehebungsreferenz
Schnelldiagnose
# Container health
docker compose ps | grep -E "(healthy|Up)"
# Network connectivity
docker network inspect proxy
# Database connection
docker compose exec windmill-db psql -U postgres -d windmill_pizza -c "SELECT version();"
# Log analysis
docker compose logs --tail 50 windmill-server | grep -E "(ERROR|WARN)"
Häufige Fehlermuster
- "password authentication failed" -- Verwenden Sie Hex-Passwörter, Volumes löschen
- "connection refused" -- Netzwerkkonfiguration überprüfen
- "certificate errors" -- DNS und Traefik-Setup verifizieren
- "out of memory" -- Worker-Ressourcenlimits anpassen
Skalierung Ihrer Windmill-Infrastruktur
Horizontale Skalierung
Für Hochlast-Umgebungen:
# Add additional workers
windmill-worker-2:
image: ${WM_IMAGE}
container_name: windmill-pizza-worker-2
environment:
- DATABASE_URL=${DATABASE_URL}
- MODE=worker
- WORKER_GROUP=heavy
deploy:
resources:
limits:
cpus: '2'
memory: 4G
Vertikale Skalierung
Server-Ressourcen upgraden:
- CX31 (8 GB RAM): 16,07 €/Monat für schwere Workloads
- CX41 (16 GB RAM): 29,75 €/Monat für Enterprise-Nutzung
Integration mit bestehender Infrastruktur
Zusammenarbeit mit n8n
Wenn Sie bereits n8n betreiben (aus unseren früheren Tutorials):
- Windmill behandelt Code-First-Workflows
- n8n behandelt visuelle, einfache Automatisierungen
- Beide teilen denselben Traefik-Proxy
- Separate Datenbanken verhindern Konflikte
Gemeinsam genutzte Dienste
Bestehende Infrastruktur nutzen:
- Traefik: Verwaltet SSL für alle Dienste
- Mailserver: Gemeinsames SMTP für Benachrichtigungen
- Monitoring: Einheitliches Logging und Metriken
- Backups: Zentralisierte Backup-Strategie
Fazit
Self-Hosting von Windmill bietet Enterprise-Grade-Workflow-Automatisierung zu einem Bruchteil der Cloud-Hosting-Kosten. Der Schlüssel zum Erfolg ist das Verständnis der PostgreSQL-Authentifizierungsanforderungen und die Verwendung reiner Hex-Passwörter, um Sonderzeichenprobleme zu vermeiden, die Installationen zum Scheitern bringen können.
Wichtigste Vorteile dieses Setups
- Kosteneffizient: Hunderte Euro jährlich sparen im Vergleich zu Cloud-Lösungen
- Produktionsreif: Bewältigt Enterprise-Workloads zuverlässig
- Sicher: HTTPS, isolierte Netzwerke und Ressourcenlimits
- Skalierbar: Einfach Worker und Ressourcen nach Bedarf hinzufügen
- Privat: Ihr Code und Ihre Daten verlassen nie Ihre Infrastruktur
Diese Konfiguration wurde in Produktionsumgebungen getestet und bietet die Zuverlässigkeit, die für geschäftskritische Workflow-Automatisierung benötigt wird. Die Fehlerbehebungsschritte behandeln reale Probleme, die beim Deployment aufgetreten sind, insbesondere die PostgreSQL-Authentifizierungsprobleme, die viele Self-Hosted-Installationen betreffen.
Für komplexe Workflow-Anforderungen oder Enterprise-Deployments sollten Sie professionelle Beratung in Betracht ziehen, um Ihren spezifischen Anwendungsfall zu optimieren und eine optimale Ressourcenzuweisung sicherzustellen.
Nächste Schritte
- Erkunden Sie Webhook-Fehlerbehebungstechniken, die auch für Windmill gelten
- Prüfen Sie Payload-Optimierung für den Umgang mit großen Datensätzen
- Erwägen Sie die Integration mit bestehenden n8n-Installationen
Über tva
tva gewährleistet umfassendes Infrastrukturmanagement von Datenbanksystemen, Cloud-Umgebungen und globalen Lieferketten. Unser methodischer Ansatz verbindet strenge Sicherheitsprotokolle mit Leistungsoptimierung, während strategische Beratungsdienstleistungen eine präzise Koordination sowohl digitaler Fähigkeiten als auch physischer Ressourcen ermöglichen – unter Einhaltung höchster Standards operativer Exzellenz und Compliance in allen Engagements.
Besuchen Sie tva.sg für weitere Informationen über unsere Dienstleistungen und zusätzliche Automatisierungs-Tutorials.