Auto-hospedagem do Windmill no Ubuntu: tutorial completo de configuração com Docker com resolução de problemas do 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 do Windmill no Ubuntu com Docker Compose e integração com o Traefik, superando problemas críticos de autenticação do PostgreSQL que podem inviabilizar sua instalação.
O que você vai construir
Ao final deste tutorial, você terá:
- Instalação do 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
- Integração com a infraestrutura Docker existente
- Configuração pronta para produção voltada à automação profissional de fluxos de trabalho
Custo mensal: a partir de €5,99 sem IVA, incluindo um endereço IPv4 primário (Hetzner CX23, 4 GB RAM, em outubro de 2026) + 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 do n8n para configuração do Traefik)
- Nome de domínio apontando para o IP do seu servidor
- Pelo menos 4GB de RAM e 2 vCPUs recomendados
- Acesso SSH e conhecimento básico de linha de comando
Entendendo o Windmill
O Windmill é um mecanismo 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 gerenciamento de execução
- Recursos de integração via API
- Recursos de colaboração em equipe
- Auto-hospedável, com execuções ilimitadas na Community Edition gratuita
Diferentemente da abordagem baseada em nós do n8n, o Windmill se concentra 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 do 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 do Windmill:
- Primeira instância:
pizza - Instâncias adicionais:
pasta,salad,soup,burger, etc. - Isso evita conflitos e facilita o gerenciamento
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-pizza-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
chmod 600 /opt/windmill-pizza/.env
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 nos rótulos 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 do Windmill falha, e foi necessário um trabalho considerável de diagnóstico para identificar a causa raiz:
O problema: caracteres especiais em senhas
Ao usar openssl rand -base64 32 para gerar senhas, a saída pode conter +, / e =. Em DATABASE_URL, esses caracteres devem ser codificados com codificação percentual; sem codificação, podem comprometer a interpretação da URL e se manifestar como falhas de autenticação do PostgreSQL. Senhas hexadecimais dispensam totalmente essa etapa de codificação.
Exemplo de senha problemática:
# This WILL cause authentication failures:
PASSWORD="305t6m9KrC/kvbyNEF+EYQ6pqAGlApn9rbJPH3D5y9g="
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 do PostgreSQL
- Configuração de usuário: Use o superusuário
postgres, como na configuração de exemplo do Windmill. Um usuário personalizado só funciona após receber os papéiswindmill_adminewindmill_userexigidos pelas migrações do Windmill (consulte a documentação de auto-hospedagem do Windmill) - 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 quando ele for acessível apenas pela rede interna do Docker, como na configuração de exemplo do Windmill; use um modo SSL comorequirepara bancos de dados acessados por outras redes
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 do PostgreSQL
Sintomas:
windmill-pizza-server | Error: password authentication failed for user "postgres"
Solução: Isso exclui todos os dados do banco de dados do Windmill. Use este procedimento apenas em uma instalação nova ou após um backup verificado. Os dois comandos sed gravam a nova senha em POSTGRES_PASSWORD e em DATABASE_URL.
# 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#postgresql://postgres:[^@]*@#postgresql://postgres:$NEW_PASSWORD@#" .env
# Restart
docker compose up -d
Problema 2: contêiner não inicia
Sintomas:
- O contêiner é encerrado 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:
[email protected] - Senha:
changeme
- E-mail:
- Conclua 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
set -euo pipefail
cd /opt/windmill-pizza
DATE=$(date +%Y%m%d_%H%M%S)
FILE=/opt/backups/windmill_pizza_${DATE}.sql
mkdir -p /opt/backups
if ! docker compose exec -T windmill-db pg_dump -U postgres windmill_pizza > "$FILE"; then
rm -f "$FILE"
echo "Backup failed" >&2
exit 1
fi
echo "Backup created: $FILE"
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 o do nosso tutorial de configuração do n8n), integre-o:
# Add to docker-compose.yml environment for windmill-server:
- SMTP_HOST=mailserver
- SMTP_PORT=25
- SMTP_USERNAME=
- SMTP_PASSWORD=
- [email protected]
Múltiplas instâncias do Windmill
Para equipes que necessitam de ambientes isolados, a segunda instância recebe seus próprios diretórios de dados vazios, banco de dados e senha:
# Create second instance with its own empty data directories
mkdir -p /opt/windmill-pasta/postgres-data /opt/windmill-pasta/windmill-data /opt/windmill-pasta/lsp-cache
cp /opt/windmill-pizza/.env /opt/windmill-pizza/docker-compose.yml /opt/windmill-pasta/
chmod 600 /opt/windmill-pasta/.env
# 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
sed -i "s#postgresql://postgres:[^@]*@#postgresql://postgres:$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
- O PostgreSQL só é acessível a partir de contêineres na rede Docker compartilhada
proxy; use uma rede interna separada para um isolamento mais rigoroso - Nenhuma porta de banco de dados externa exposta
- Terminação HTTPS no nível do Traefik
Limites de recursos
- Contêineres de workers têm limites de CPU e memória
- Os limites de recursos reduzem o impacto de tarefas fora de controle e de tentativas 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
# Backup database first
cd /opt/windmill-pizza
./backup.sh
# Update containers
./update.sh
# Clean old data
docker system prune -f
Detalhamento de custos e comparação
Custos mensais
Configuração auto-hospedada:
- Hetzner CX23 (4 GB RAM): €5,99/mês sem IVA, incluindo um endereço IPv4 primário (em outubro de 2026)
- Custos de domínio: ~€1/mês
- Total: ~€7/mês sem IVA
Comparação com Windmill Cloud:
- Cloud: $20/mês por licença de desenvolvedor, $10/mês por operador (em outubro de 2026)
- Economia: $250+ por ano quando dois ou mais desenvolvedores precisam de licenças
Benefícios de desempenho
Vantagens da auto-hospedagem:
- Execuções de fluxos de trabalho ilimitadas
- Sem limites externos de requisições
- 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; esvazie os volumes apenas após um backup ou em uma instalação nova
- "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 (preços da Hetzner sem IVA, incluindo um endereço IPv4 primário em outubro de 2026):
- CX33 (8 GB RAM): €8,99/mês para cargas de trabalho pesadas
- CX43 (16 GB RAM): €16,49/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 evitam 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: Registros de logs e métricas unificados
- Backups: Estratégia centralizada de backup
Conclusão
A auto-hospedagem 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 como as credenciais do PostgreSQL são transmitidas e persistidas e usar senhas apenas em hexadecimal para evitar problemas de codificação de URL que podem inviabilizar instalações.
Principais benefícios desta configuração
- Econômico: Economize centenas por ano em comparação com soluções em nuvem
- Pronto para produção: Lida com cargas de trabalho empresariais de forma confiável
- Seguro: HTTPS, nenhuma porta do banco de dados exposta e limites de recursos (a montagem do socket Docker ainda concede ao worker acesso ao host)
- Escalável: Fácil adicionar workers e recursos conforme necessário
- Privado: Seu código e dados permanecem na sua infraestrutura, a menos que seus fluxos de trabalho os enviem a serviços externos
Esta configuração foi testada em ambientes de produção e fornece a confiabilidade necessária para a automação de fluxos de trabalho essenciais aos negócios. Os passos de resolução de problemas abordam questões reais encontradas durante a implantação, particularmente os problemas de autenticação do 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 uma alocação ideal 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 o gerenciamento 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 recursos digitais e ativos físicos — mantendo os mais altos padrões de excelência operacional e conformidade em todos os projetos.
Visite tva.sg para mais informações sobre nossos serviços e tutoriais adicionais de automação.