Self-Hosting do Windmill no Ubuntu: Tutorial Completo de Configuração Docker com Resolução de Problemas PostgreSQL
Plataformas de automação de fluxos de trabalho são essenciais para equipes modernas de desenvolvimento, mas soluções em nuvem como o Windmill Cloud podem se tornar caras conforme o uso cresce. Vamos mostrar como configurar sua própria instância Windmill no Ubuntu com Docker Compose e integração Traefik, superando problemas críticos de autenticação PostgreSQL que podem inviabilizar sua instalação.
O Que Você Vai Construir
Ao final deste tutorial, você terá:
- Instalação Windmill totalmente funcional com HTTPS
- Certificados SSL automáticos via Let's Encrypt através do Traefik
- Banco de dados PostgreSQL pronto para produção com autenticação adequada
- Configuração de worker otimizada para recursos
- Integrado com infraestrutura Docker existente
- Configuração pronta para produção para automação profissional de fluxos de trabalho
Custo mensal: €4,51 (servidor CX11) + custos de domínio -- mesma infraestrutura que pode lidar com múltiplas ferramentas de automação
Pré-requisitos
- Servidor Ubuntu 24.04 LTS com Docker e Docker Compose instalados
- Configuração existente de proxy reverso Traefik (veja nosso guia de configuração n8n para configuração do Traefik)
- Nome de domínio apontando para o IP do seu servidor
- Mínimo de 4GB de RAM e 2 vCPUs recomendados
- Acesso SSH e conhecimento básico de linha de comando
Entendendo o Windmill
Windmill é um motor de fluxos de trabalho de código aberto que oferece:
- Editor visual de fluxos de trabalho com suporte a TypeScript/Python/Go
- Agendamento de tarefas e gestão de execução
- Capacidades de integração via API
- Recursos de colaboração em equipe
- Auto-hospedável sem limites de uso
Diferentemente da abordagem baseada em nós do n8n, o Windmill foca em fluxos de trabalho orientados a código com um poderoso ambiente de desenvolvimento.
Passo 1: Preparação do Servidor e Estrutura de Diretórios
Primeiro, vamos preparar nosso ambiente de servidor. Usaremos uma convenção de nomenclatura baseada em alimentos para instâncias Windmill para evitar conflitos:
# 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
Convenção de Nomenclatura: Use nomes simples de alimentos para múltiplas instâncias Windmill:
- Primeira instância:
pizza - Instâncias adicionais:
pasta,salad,soup,burger, etc. - Isso evita conflitos e facilita a gestão
Passo 2: Configuração do Ambiente
Crie um arquivo de ambiente seguro com credenciais adequadas:
# 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
Crítico: Substitua windmill.yourdomain.com pelo seu domínio real!
Passo 3: Configuração do Docker Compose
Crie a configuração principal do 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
Importante: Atualize o domínio nas labels do Traefik para corresponder à sua configuração!
Passo 4: O Problema de Senha do PostgreSQL (Questão Crítica)
Aqui é onde a maioria das instalações Windmill falha, e foi necessária considerável resolução de problemas para identificar a causa raiz:
O Problema: Caracteres Especiais em Senhas
Ao usar openssl rand -base64 32 para gerar senhas, frequentemente surgem caracteres especiais como =, @, #, %, etc. Esses caracteres causam falhas de autenticação PostgreSQL em ambientes Docker, mesmo quando devidamente escapados.
Exemplo de senha problemática:
# This WILL cause authentication failures:
PASSWORD="305t6m9KrChkvbyNEFLEYQ6pqAGlApn9rbJPH3D5y9g="
A Solução: Senhas Apenas em Hexadecimal
Use senhas apenas em hexadecimal que não contêm caracteres especiais:
# This WORKS reliably:
PASSWORD=$(openssl rand -hex 16)
# Example result: 5781b14ec0ec1bc184653ffa5e379411
Problemas Adicionais de Configuração PostgreSQL
- Configuração de Usuário: Use
postgrescomo usuário padrão, não usuários personalizados comowindmill_user - Persistência de Volume: O PostgreSQL ignora variáveis de ambiente
POSTGRES_PASSWORDquando volumes de dados existentes contêm credenciais diferentes - Formato da URL: Inclua
?sslmode=disablena URL do banco de dados para ambientes Docker
Passo 5: Instalação e Inicialização
Agora vamos instalar o Windmill com nossa configuração corrigida:
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
Você deve ver uma saída como:
NAME STATUS PORTS
windmill-pizza-db Up (healthy) 5432/tcp
windmill-pizza-server Up 8000/tcp
windmill-pizza-worker Up 8000/tcp
Passo 6: Resolução de Problemas Comuns
Problema 1: Falhas de Autenticação PostgreSQL
Sintomas:
windmill-pizza-server | Error: password authentication failed for user "postgres"
Solução:
# 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
Problema 2: Contêiner Não Inicia
Sintomas:
- Contêiner encerra imediatamente
- Erros de alocação de recursos
Solução:
# Check container logs
docker logs windmill-pizza-server
docker logs windmill-pizza-db
# Check system resources
docker stats
free -h
Problema 3: Problemas de Certificado SSL
Sintomas:
- HTTPS não funciona
- Erros de certificado
Solução:
# Check Traefik logs
docker logs traefik
# Verify DNS resolution
nslookup windmill.yourdomain.com
# Restart Traefik if needed
docker restart traefik
Passo 7: Acesso e Configuração Inicial
Após a instalação ser concluída:
- Acesse o Windmill: https://windmill.yourdomain.com
- Credenciais padrão:
- E-mail:
admin@windmill.dev - Senha:
changeme
- E-mail:
- Complete a configuração:
- Altere a senha do administrador
- Configure a URL base
- Configure contas de usuário
Passo 8: Otimização de Recursos
Alocação de Memória (para servidor de 8GB)
Nossa configuração aloca recursos de forma eficiente:
- Servidor Windmill: ~800MB
- Worker Windmill: 2GB (limitado)
- PostgreSQL: ~500MB
- Reserva do Sistema: ~4,7GB
Alocação de CPU (para servidor de 4 vCPU)
- Worker: 1 vCPU (limitado)
- Outros serviços: 3 vCPUs (compartilhados)
Regra de escala: 1 worker por vCPU com 1-2GB de RAM cada
Passo 9: Preparação para Produção
Criar Script de Backup
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
Configurar Monitoramento
# Monitor container health
docker compose ps
# Check resource usage
docker stats
# Monitor logs
docker compose logs -f windmill-server
Configurar Atualizações Automatizadas
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
Passo 10: Configuração Avançada
Integração com SMTP Existente
Se você tem um servidor de e-mail (como do nosso tutorial de configuração n8n), integre-o:
# Add to docker-compose.yml environment for windmill-server:
- SMTP_HOST=mailserver
- SMTP_PORT=25
- SMTP_USERNAME=
- SMTP_PASSWORD=
- SMTP_FROM=noreply@yourdomain.com
Múltiplas Instâncias Windmill
Para equipes que necessitam de ambientes isolados:
# 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
Considerações de Segurança
Isolamento de Rede
- PostgreSQL acessível apenas dentro da rede Docker
- Nenhuma porta de banco de dados externa exposta
- Terminação HTTPS no nível do Traefik
Limites de Recursos
- Contêineres worker têm limites de CPU e memória
- Previne ataques de esgotamento de recursos
- Configurável com base na capacidade do servidor
Segurança SSL
- Certificados automáticos Let's Encrypt
- Redirecionamentos HTTP para HTTPS
- Configuração TLS moderna
Monitoramento e Manutenção
Verificações Semanais de Saúde
# Container status
docker compose ps
# Resource usage
docker stats --no-stream
# Log analysis
docker compose logs | grep -i error
Manutenção Mensal
# Update containers
cd /opt/windmill-pizza
./update.sh
# Clean old data
docker system prune -f
# Backup database
./backup.sh
Detalhamento de Custos e Comparação
Custos Mensais
Configuração auto-hospedada:
- Hetzner CX21 (4GB RAM): €8,46/mês
- Custos de domínio: ~€1/mês
- Total: ~€9,50/mês
Comparação com Windmill Cloud:
- Plano Team: $30/mês por usuário
- Economia: $250+ anualmente para equipes pequenas
Benefícios de Desempenho
Vantagens do auto-hospedamento:
- Execuções de fluxos de trabalho ilimitadas
- Sem limites de taxa externos
- Controle total dos dados
- Integrações personalizadas
- Flexibilidade de escala de recursos
Referência de Resolução de Problemas
Diagnóstico Rápido
# 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)"
Padrões Comuns de Erro
- "password authentication failed" → Use senhas hexadecimais, limpe volumes
- "connection refused" → Verifique configuração de rede
- "certificate errors" → Verifique DNS e configuração do Traefik
- "out of memory" → Ajuste limites de recursos do worker
Escalando Sua Infraestrutura Windmill
Escalabilidade Horizontal
Para ambientes de alto 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
Escalabilidade Vertical
Faça upgrade dos recursos do servidor:
- CX31 (8GB RAM): €16,07/mês para cargas de trabalho pesadas
- CX41 (16GB RAM): €29,75/mês para uso empresarial
Integração com Infraestrutura Existente
Trabalhando com n8n
Se você já está executando n8n (dos nossos tutoriais anteriores):
- Windmill lida com fluxos de trabalho orientados a código
- n8n lida com automações visuais e simples
- Ambos compartilham o mesmo proxy Traefik
- Bancos de dados separados previnem conflitos
Serviços Compartilhados
Aproveite a infraestrutura existente:
- Traefik: Gerencia SSL para todos os serviços
- Servidor de E-mail: SMTP compartilhado para notificações
- Monitoramento: Logging e métricas unificados
- Backups: Estratégia centralizada de backup
Conclusão
O auto-hospedamento do Windmill fornece automação de fluxos de trabalho de nível empresarial a uma fração dos custos de hospedagem em nuvem. A chave para o sucesso é entender os requisitos de autenticação do PostgreSQL e usar senhas apenas em hexadecimal para evitar problemas com caracteres especiais que podem inviabilizar instalações.
Principais Benefícios Desta Configuração
- Econômico: Economize centenas anualmente comparado a soluções em nuvem
- Pronto para produção: Lida com cargas de trabalho empresariais de forma confiável
- Seguro: HTTPS, redes isoladas e limites de recursos
- Escalável: Fácil adicionar workers e recursos conforme necessário
- Privado: Seu código e dados nunca saem da sua infraestrutura
Esta configuração foi testada em ambientes de produção e fornece a confiabilidade necessária para automação de fluxos de trabalho críticos para os negócios. Os passos de resolução de problemas abordam questões reais encontradas durante a implantação, particularmente os problemas de autenticação PostgreSQL que afetam muitas instalações auto-hospedadas.
Para requisitos complexos de fluxos de trabalho ou implantações empresariais, considere consultoria profissional para otimizar seu caso de uso específico e garantir alocação otimizada de recursos.
Próximos Passos
- Explore técnicas de resolução de problemas de webhook aplicáveis ao Windmill
- Revise otimização de payload para lidar com grandes conjuntos de dados
- Considere integração com instalações n8n existentes
Sobre a tva
A tva assegura a gestão abrangente de infraestrutura de sistemas de banco de dados, ambientes em nuvem e cadeias de suprimentos globais. Nossa abordagem metódica combina protocolos rigorosos de segurança com otimização de desempenho, enquanto os serviços de consultoria estratégica permitem a coordenação precisa de capacidades digitais e ativos físicos -- mantendo os mais altos padrões de excelência operacional e conformidade em todos os engajamentos.
Visite tva.sg para mais informações sobre nossos serviços e tutoriais adicionais de automação.