tva
← Insights

Auto-hébergement de Windmill sur Ubuntu : tutoriel complet de configuration Docker avec résolution de problèmes PostgreSQL

Les plateformes d'automatisation de workflows sont essentielles pour les équipes de développement modernes, mais les solutions cloud comme Windmill Cloud peuvent devenir coûteuses à mesure que l'utilisation augmente. Nous vous montrons comment configurer votre propre instance Windmill sur Ubuntu avec Docker Compose et l'intégration Traefik, en surmontant les problèmes critiques d'authentification PostgreSQL qui peuvent faire échouer votre installation.

Ce que vous allez construire

À la fin de ce tutoriel, vous disposerez de :

  • Une installation Windmill entièrement fonctionnelle avec HTTPS
  • Certificats SSL automatiques via Let's Encrypt à travers Traefik
  • Base de données PostgreSQL prête pour la production avec authentification correcte
  • Configuration de workers optimisée en ressources
  • Intégration avec l'infrastructure Docker existante
  • Configuration prête pour la production pour l'automatisation professionnelle des workflows

Coût mensuel : 4,51 € (serveur CX11) + coûts de domaine – la même infrastructure peut gérer plusieurs outils d'automatisation

Prérequis

  • Serveur Ubuntu 24.04 LTS avec Docker et Docker Compose installés
  • Configuration existante du proxy inverse Traefik (voir notre guide de configuration n8n pour la configuration Traefik)
  • Nom de domaine pointant vers l'IP de votre serveur
  • Au moins 4 Go de RAM et 2 vCPU recommandés
  • Accès SSH et connaissances de base en ligne de commande

Comprendre Windmill

Windmill est un moteur de workflows open source qui fournit :

  • Éditeur visuel de workflows avec support TypeScript/Python/Go
  • Planification de tâches et gestion de l'exécution
  • Capacités d'intégration API
  • Fonctionnalités de collaboration d'équipe
  • Auto-hébergeable sans limites d'utilisation

Contrairement à l'approche par nœuds de n8n, Windmill se concentre sur les workflows orientés code avec un puissant environnement de développement.

Étape 1 : Préparation du serveur et structure des répertoires

Tout d'abord, préparons notre environnement serveur. Nous utiliserons une convention de nommage basée sur la nourriture pour les instances Windmill afin d'éviter les conflits :

# 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

Convention de nommage : Utilisez des noms de plats simples pour les instances Windmill multiples :

  • Première instance : pizza
  • Instances supplémentaires : pasta, salad, soup, burger, etc.
  • Cela évite les conflits et facilite la gestion

Étape 2 : Configuration de l'environnement

Créez un fichier d'environnement sécurisé avec des identifiants adéquats :

# 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

Critique : Remplacez windmill.yourdomain.com par votre domaine réel !

Étape 3 : Configuration Docker Compose

Créez la configuration Docker Compose principale :

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

Important : Mettez à jour le domaine dans les labels Traefik pour correspondre à votre configuration !

Étape 4 : Le problème des mots de passe PostgreSQL (problème critique)

C'est ici que la plupart des installations Windmill échouent, et il a fallu un dépannage considérable pour identifier la cause profonde :

Le problème : les caractères spéciaux dans les mots de passe

Lors de l'utilisation de openssl rand -base64 32 pour générer des mots de passe, vous obtenez souvent des caractères spéciaux comme =@#%, etc. Ces caractères causent des échecs d'authentification PostgreSQL dans les environnements Docker, même lorsqu'ils sont correctement échappés.

Exemple de mot de passe problématique :

# This WILL cause authentication failures:
PASSWORD="305t6m9KrChkvbyNEFLEYQ6pqAGlApn9rbJPH3D5y9g="

La solution : des mots de passe hexadécimaux uniquement

Utilisez des mots de passe hexadécimaux qui ne contiennent aucun caractère spécial :

# This WORKS reliably:
PASSWORD=$(openssl rand -hex 16)
# Example result: 5781b14ec0ec1bc184653ffa5e379411

Problèmes de configuration PostgreSQL supplémentaires

  1. Configuration utilisateur : Utilisez postgres comme utilisateur par défaut, pas des utilisateurs personnalisés comme windmill_user
  2. Persistance des volumes : PostgreSQL ignore les variables d'environnement POSTGRES_PASSWORD lorsque les volumes de données existants contiennent des identifiants différents
  3. Format d'URL : Incluez ?sslmode=disable dans l'URL de la base de données pour les environnements Docker

Étape 5 : Installation et démarrage

Installons maintenant Windmill avec notre configuration corrigée :

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

Vous devriez voir une sortie comme :

NAME                    STATUS                    PORTS
windmill-pizza-db       Up (healthy)              5432/tcp
windmill-pizza-server   Up                        8000/tcp
windmill-pizza-worker   Up                        8000/tcp

Étape 6 : Résolution des problèmes courants

Problème 1 : Échecs d'authentification PostgreSQL

Symptômes :

windmill-pizza-server | Error: password authentication failed for user "postgres"

Solution :

# 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

Problème 2 : Le conteneur ne démarre pas

Symptômes :

  • Le conteneur se ferme immédiatement
  • Erreurs d'allocation de ressources

Solution :

# Check container logs
docker logs windmill-pizza-server
docker logs windmill-pizza-db

# Check system resources
docker stats
free -h

Problème 3 : Problèmes de certificat SSL

Symptômes :

  • HTTPS ne fonctionne pas
  • Erreurs de certificat

Solution :

# Check Traefik logs
docker logs traefik

# Verify DNS resolution
nslookup windmill.yourdomain.com

# Restart Traefik if needed
docker restart traefik

Étape 7 : Accès et configuration initiale

Une fois l'installation terminée :

  1. Accédez à Windmill : https://windmill.yourdomain.com
  2. Identifiants par défaut :
    • Email : admin@windmill.dev
    • Mot de passe : changeme
  3. Complétez la configuration :
    • Changez le mot de passe administrateur
    • Configurez l'URL de base
    • Créez les comptes utilisateurs

Étape 8 : Optimisation des ressources

Allocation mémoire (pour un serveur de 8 Go)

Notre configuration alloue les ressources efficacement :

  • Serveur Windmill : ~800 Mo
  • Worker Windmill : 2 Go (limité)
  • PostgreSQL : ~500 Mo
  • Réserve système : ~4,7 Go

Allocation CPU (pour un serveur 4 vCPU)

  • Worker : 1 vCPU (limité)
  • Autres services : 3 vCPU (partagés)

Règle de dimensionnement : 1 worker par vCPU avec 1-2 Go de RAM chacun

Étape 9 : Renforcement pour la production

Créer un script de sauvegarde

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

Configurer la surveillance

# Monitor container health
docker compose ps

# Check resource usage
docker stats

# Monitor logs
docker compose logs -f windmill-server

Configurer les mises à jour automatisées

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

Étape 10 : Configuration avancée

Intégration avec un serveur SMTP existant

Si vous avez un serveur de messagerie (comme dans notre configuration n8n), intégrez-le :

# Add to docker-compose.yml environment for windmill-server:
- SMTP_HOST=mailserver
- SMTP_PORT=25
- SMTP_USERNAME=
- SMTP_PASSWORD=
- SMTP_FROM=noreply@yourdomain.com

Instances Windmill multiples

Pour les équipes nécessitant des environnements isolés :

# 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

Considérations de sécurité

Isolation réseau

  • PostgreSQL accessible uniquement au sein du réseau Docker
  • Aucun port de base de données externe exposé
  • Terminaison HTTPS au niveau de Traefik

Limites de ressources

  • Les conteneurs workers ont des limites CPU et mémoire
  • Prévient les attaques par épuisement de ressources
  • Configurable selon la capacité du serveur

Sécurité SSL

  • Certificats Let's Encrypt automatiques
  • Redirections HTTP vers HTTPS
  • Configuration TLS moderne

Surveillance et maintenance

Vérifications de santé hebdomadaires

# Container status
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)"

Maintenance mensuelle

# Update containers
cd /opt/windmill-pizza
./update.sh

# Clean old data
docker system prune -f

# Backup database
./backup.sh

Décomposition des coûts et comparaison

Coûts mensuels

Configuration auto-hébergée :

  • Hetzner CX21 (4 Go de RAM) : 8,46 €/mois
  • Coûts de domaine : ~1 €/mois
  • Total : ~9,50 €/mois

Comparaison avec Windmill Cloud :

  • Forfait Team : 30 $/mois par utilisateur
  • Économies : 250 $+ par an pour les petites équipes

Avantages en termes de performance

Avantages de l'auto-hébergement :

  • Exécutions de workflows illimitées
  • Aucune limitation de débit externe
  • Contrôle total des données
  • Intégrations personnalisées
  • Flexibilité de dimensionnement des ressources

Référence de dépannage

Diagnostics rapides

# 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)"

Erreurs courantes

  1. « password authentication failed » → Utilisez des mots de passe hexadécimaux, videz les volumes
  2. « connection refused » → Vérifiez la configuration réseau
  3. « certificate errors » → Vérifiez le DNS et la configuration Traefik
  4. « out of memory » → Ajustez les limites de ressources des workers

Évolutivité de votre infrastructure Windmill

Évolutivité horizontale

Pour les environnements à haut volume :

# 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

Évolutivité verticale

Augmentez les ressources du serveur :

  • CX31 (8 Go de RAM) : 16,07 €/mois pour les charges de travail lourdes
  • CX41 (16 Go de RAM) : 29,75 €/mois pour un usage entreprise

Intégration avec l'infrastructure existante

Travail avec n8n

Si vous utilisez déjà n8n (de nos tutoriels précédents) :

  • Windmill gère les workflows orientés code
  • n8n gère les automatisations visuelles et simples
  • Les deux partagent le même proxy Traefik
  • Des bases de données séparées évitent les conflits

Services partagés

Exploitez l'infrastructure existante :

  • Traefik : Gère le SSL pour tous les services
  • Serveur de messagerie : SMTP partagé pour les notifications
  • Surveillance : Journalisation et métriques unifiées
  • Sauvegardes : Stratégie de sauvegarde centralisée

Conclusion

L'auto-hébergement de Windmill fournit une automatisation des workflows de niveau entreprise à une fraction des coûts d'hébergement cloud. La clé du succès est de comprendre les exigences d'authentification PostgreSQL et d'utiliser des mots de passe hexadécimaux uniquement pour éviter les problèmes de caractères spéciaux qui peuvent faire échouer les installations.

Principaux avantages de cette configuration

  • Rentable : Économisez des centaines de dollars par an par rapport aux solutions cloud
  • Prêt pour la production : Gère de manière fiable les charges de travail entreprise
  • Sécurisé : HTTPS, réseaux isolés et limites de ressources
  • Évolutif : Facile d'ajouter des workers et des ressources selon les besoins
  • Privé : Votre code et vos données ne quittent jamais votre infrastructure

Cette configuration a été testée dans des environnements de production et offre la fiabilité nécessaire pour l'automatisation de workflows critiques. Les étapes de dépannage répondent aux problèmes rencontrés en conditions réelles lors du déploiement, en particulier les problèmes d'authentification PostgreSQL qui affectent de nombreuses installations auto-hébergées.

Pour des exigences de workflows complexes ou des déploiements d'entreprise, envisagez une consultation professionnelle pour optimiser votre cas d'utilisation spécifique et garantir une allocation optimale des ressources.

Prochaines étapes


À propos de tva

tva assure la gestion complète de l'infrastructure des systèmes de bases de données, des environnements cloud et des chaînes d'approvisionnement mondiales. Notre approche méthodique combine des protocoles de sécurité rigoureux avec l'optimisation des performances, tandis que nos services de conseil stratégique permettent une coordination précise des capacités numériques et des actifs physiques – maintenant les plus hauts standards d'excellence opérationnelle et de conformité dans tous nos engagements.

Visitez tva.sg pour plus d'informations sur nos services et nos tutoriels d'automatisation supplémentaires.