tva
← Insights

UbuntuでのWindmillセルフホスティング:PostgreSQLトラブルシューティング付き完全Dockerセットアップチュートリアル

ワークフロー自動化プラットフォームは現代の開発チームに不可欠ですが、Windmill Cloudのようなクラウドソリューションは使用量の増加に伴いコストが高くなる可能性があります。Docker ComposeとTraefik統合を使用してUbuntu上に独自のWindmillインスタンスをセットアップする方法を、インストールを妨げる可能性のある重大なPostgreSQL認証の問題を克服しながらご紹介いたします。

構築するもの

このチュートリアルの終わりには、以下が構築されます:

  • HTTPS付きの完全に機能するWindmillインストール
  • Traefik経由のLet’s Encryptによる自動SSL証明書
  • 適切な認証を備えた本番対応のPostgreSQLデータベース
  • リソース最適化されたワーカー設定
  • 既存のDockerインフラとの統合
  • プロフェッショナルなワークフロー自動化のための本番対応セットアップ

月額コスト: 4.51ユーロ(CX11サーバー)+ ドメインコスト – 複数の自動化ツールを処理できる同一のインフラ

前提条件

  • DockerとDocker Composeがインストールされた Ubuntu 24.04 LTSサーバー
  • 既存のTraefikリバースプロキシセットアップ(Traefik設定についてはn8nセットアップガイドをご参照ください)
  • サーバーIPに向けられたドメイン名
  • 最低4GB RAMと2 vCPUを推奨
  • SSHアクセスと基本的なコマンドラインの知識

Windmillの理解

Windmillは以下を提供するオープンソースのワークフローエンジンです:

  • TypeScript/Python/Goサポート付きのビジュアルワークフローエディター
  • ジョブスケジューリングと実行管理
  • API統合機能
  • チームコラボレーション機能
  • 使用制限のないセルフホスティング対応

n8nのノードベースのアプローチとは異なり、Windmillは強力な開発環境を備えたコードファーストのワークフローに焦点を当てています。

ステップ1:サーバーの準備とディレクトリ構造

まず、サーバー環境を準備します。競合を避けるために、Windmillインスタンスには食べ物に基づく命名規則を使用します:

# 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

命名規則: 複数のWindmillインスタンスにはシンプルな食べ物の名前を使用します:

  • 最初のインスタンス:pizza
  • 追加インスタンス:pastasaladsoupburgerなど
  • 競合を回避し、管理を容易にします

ステップ2:環境設定

適切な認証情報を含む安全な環境ファイルを作成します:

# 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

重要: windmill.yourdomain.comを実際のドメインに置き換えてください。

ステップ3:Docker Compose設定

メインのDocker Compose設定を作成します:

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

重要: Traefikラベルのドメインをお客様のセットアップに合わせて更新してください。

ステップ4:PostgreSQLパスワード問題(重大な問題)

ここが、ほとんどのWindmillインストールが失敗するポイントであり、根本原因の特定にはかなりのトラブルシューティングが必要でした:

問題:パスワード内の特殊文字

openssl rand -base64 32を使用してパスワードを生成すると、=@#%などの特殊文字が含まれることがよくあります。これらの文字は、適切にエスケープされていても、Docker環境でPostgreSQL認証の失敗を引き起こします。

問題のあるパスワードの例:

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

解決策:16進数のみのパスワード

特殊文字を含まない16進数のみのパスワードを使用します:

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

追加のPostgreSQL設定の問題

  1. ユーザー設定:windmill_userのようなカスタムユーザーではなく、デフォルトユーザーとしてpostgresを使用
  2. ボリュームの永続性:既存のデータボリュームに異なる認証情報が含まれている場合、PostgreSQLはPOSTGRES_PASSWORD環境変数を無視
  3. URLフォーマット:Docker環境ではデータベースURLに?sslmode=disableを含める

ステップ5:インストールと起動

修正された設定でWindmillをインストールします:

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

以下のような出力が表示されるはずです:

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

ステップ6:よくある問題のトラブルシューティング

問題1:PostgreSQL認証の失敗

症状:

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

解決策:

# 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

問題2:コンテナが起動しない

症状:

  • コンテナが即座に終了
  • リソース割り当てエラー

解決策:

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

# Check system resources
docker stats
free -h

問題3:SSL証明書の問題

症状:

  • HTTPSが機能しない
  • 証明書エラー

解決策:

# Check Traefik logs
docker logs traefik

# Verify DNS resolution
nslookup windmill.yourdomain.com

# Restart Traefik if needed
docker restart traefik

ステップ7:アクセスと初期セットアップ

インストールが完了したら:

  1. Windmillにアクセス:https://windmill.yourdomain.com
  2. デフォルト認証情報:
    • メール:admin@windmill.dev
    • パスワード:changeme
  3. セットアップを完了:
    • 管理者パスワードを変更
    • ベースURLを設定
    • ユーザーアカウントをセットアップ

ステップ8:リソース最適化

メモリ割り当て(8GBサーバーの場合)

当社の設定では、リソースを効率的に割り当てます:

  • Windmillサーバー:約800MB
  • Windmillワーカー:2GB(制限付き)
  • PostgreSQL:約500MB
  • システム予約:約4.7GB

CPU割り当て(4 vCPUサーバーの場合)

  • ワーカー:1 vCPU(制限付き)
  • その他のサービス:3 vCPU(共有)

スケーリングルール: vCPUあたり1ワーカー、各1〜2GB RAM

ステップ9:本番環境の堅牢化

バックアップスクリプトの作成

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

監視のセットアップ

# Monitor container health
docker compose ps

# Check resource usage
docker stats

# Monitor logs
docker compose logs -f windmill-server

自動アップデートの設定

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

ステップ10:高度な設定

既存SMTPとの統合

メールサーバーがある場合(当社のn8nセットアップのように)、統合します:

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

複数のWindmillインスタンス

隔離された環境を必要とするチーム向け:

# 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

セキュリティの考慮事項

ネットワーク分離

  • PostgreSQLはDockerネットワーク内からのみアクセス可能
  • 外部データベースポートの公開なし
  • TraefikレベルでのHTTPS終端

リソース制限

  • ワーカーコンテナにCPUとメモリの制限あり
  • リソース枯渇攻撃を防止
  • サーバー容量に基づいて設定可能

SSLセキュリティ

  • Let’s Encrypt証明書の自動取得
  • HTTPからHTTPSへのリダイレクト
  • 最新のTLS設定

監視とメンテナンス

週次ヘルスチェック

# Container status
docker compose ps | grep -E "(healthy|Up)"

# Resource usage
docker stats --no-stream

# Log analysis
docker compose logs | grep -i error

月次メンテナンス

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

# Clean old data
docker system prune -f

# Backup database
./backup.sh

コスト内訳と比較

月額コスト

セルフホスティングセットアップ:

  • Hetzner CX21(4GB RAM):月額8.46ユーロ
  • ドメインコスト:約月額1ユーロ
  • 合計:約月額9.50ユーロ

Windmill Cloudとの比較:

  • チームプラン:ユーザーあたり月額30ドル
  • 節約額:小規模チームで年間250ドル以上

パフォーマンスのメリット

セルフホスティングの利点:

  • 無制限のワークフロー実行
  • 外部レート制限なし
  • 完全なデータ制御
  • カスタム統合
  • リソーススケーリングの柔軟性

トラブルシューティングリファレンス

クイック診断

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

よくあるエラーパターン

  1. “password authentication failed” → 16進数パスワードを使用し、ボリュームをクリア
  2. “connection refused” → ネットワーク設定を確認
  3. “certificate errors” → DNSとTraefikセットアップを検証
  4. “out of memory” → ワーカーのリソース制限を調整

Windmillインフラのスケーリング

水平スケーリング

大量処理環境向け:

# 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

垂直スケーリング

サーバーリソースをアップグレード:

  • CX31(8GB RAM):重いワークロード向けに月額16.07ユーロ
  • CX41(16GB RAM):エンタープライズ使用向けに月額29.75ユーロ

既存インフラとの統合

n8nとの連携

すでにn8nを実行している場合(当社の以前のチュートリアルから):

  • Windmillはコードファーストのワークフローを処理
  • n8nはビジュアルでシンプルな自動化を処理
  • 両方が同じTraefikプロキシを共有
  • 別々のデータベースで競合を防止

共有サービス

既存のインフラを活用:

  • Traefik:すべてのサービスのSSLを処理
  • メールサーバー:通知用の共有SMTP
  • 監視:統一されたログとメトリクス
  • バックアップ:一元化されたバックアップ戦略

まとめ

Windmillのセルフホスティングは、クラウドホスティングコストのごく一部でエンタープライズグレードのワークフロー自動化を提供します。成功の鍵は、PostgreSQLの認証要件を理解し、インストールを妨げる可能性のある特殊文字の問題を回避するために16進数のみのパスワードを使用することです。

このセットアップの主な利点

  • コスト効率:クラウドソリューションと比較して年間数百ドルを節約
  • 本番対応:エンタープライズワークロードを確実に処理
  • 安全:HTTPS、隔離されたネットワーク、リソース制限
  • スケーラブル:必要に応じてワーカーとリソースを簡単に追加
  • プライベート:コードとデータがインフラの外に出ることはない

この設定は本番環境でテスト済みであり、ビジネスクリティカルなワークフロー自動化に必要な信頼性を提供します。トラブルシューティングの手順は、デプロイメント中に遭遇した実際の問題、特に多くのセルフホスティングインストールに影響するPostgreSQL認証の問題に対処しています。

複雑なワークフロー要件やエンタープライズデプロイメントの場合は、特定のユースケースを最適化し、最適なリソース配分を確保するためにプロフェッショナルなコンサルテーションをご検討ください。

次のステップ


tvaについて

tvaは、データベースシステム、クラウド環境、グローバルサプライチェーンの包括的なインフラ管理を担っています。当社の体系的なアプローチは、厳格なセキュリティプロトコルとパフォーマンス最適化を組み合わせ、戦略的アドバイザリーサービスによりデジタル能力と物理的資産の両方の精密な調整を可能にし、すべてのエンゲージメントにおいて最高水準の運営卓越性とコンプライアンスを維持しています。

当社のサービスおよび追加の自動化チュートリアルの詳細については、 tva.sg をご覧ください。