tva
← Artigos

Auto-hospedagem do Windmill em 2026: workers, PostgreSQL, isolamento e atualizações seguras

Um artigo complementar atualizado, voltado à produção, que transforma as orientações dos fornecedores em controles operacionais, decisões de migração e critérios verificáveis para o lançamento.

O que mudou em 2026

Voltamos a este tema porque os limites operacionais mudaram. Os princípios duradouros continuam válidos, mas as versões atuais tornam alguns atalhos anteriores incompletos ou arriscados. Este artigo parte da documentação oficial disponível em 14 de julho de 2026, distingue fatos de escolhas locais e trata cada alteração de configuração como uma intervenção controlada em produção.

Fontes primárias atuais

Como utilizar esta atualização

Leia primeiro as fontes, registre as versões efetivamente implantadas e defina o resultado observável antes de alterar uma configuração. Teste a menor intervenção reversível em um ambiente representativo. Um comando concluído com sucesso não é o critério de aceitação: os critérios são o funcionamento do serviço, a integridade dos dados, a latência, os limites de segurança e o tempo de reversão. Quando o guia anterior oferece uma sequência de diagnóstico útil, nós a mantemos abaixo como base operacional; os exemplos específicos de cada versão ainda precisam ser conferidos na documentação atual.

Antes do lançamento, registre as diferenças de configuração, um backup ou snapshot que tenha sido restaurado pelo menos uma vez e os comandos necessários para reverter a intervenção. Designe uma pessoa para observar a primeira janela de produção e outra para aprovar o encaminhamento ao responsável se os indicadores esperados evoluírem na direção errada. Os alertas devem descrever o risco visível para o usuário, e não apenas o componente que os emitiu. Durante a janela de verificação dos resultados, compare as taxas de erro, o tamanho das filas, a saturação de recursos, a latência de processamento e a completude dos dados com a linha de base acordada. Analise tanto as médias quanto os valores extremos, pois uma média estável pode ocultar falhas que afetam uma parcela pequena, mas importante, do trabalho. Encerre a alteração somente depois de concluídas as tarefas atrasadas, as novas tentativas, as tarefas agendadas e as exportações para os sistemas subsequentes. Registre toda ação manual realizada durante a recuperação; uma intervenção de emergência não documentada indica que o procedimento operacional ainda está incompleto. Essa disciplina de lançamento gera evidências que podem ser reutilizadas na próxima atualização, em vez de obrigar a equipe a redescobrir as mesmas dependências.

Base operacional

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, com um endereço IPv4 primário incluído (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)

# Create environment file
cat > /opt/windmill-pizza/.env << EOF
# Windmill Image Version (pin a release; change it deliberately when you update)
WM_IMAGE=ghcr.io/windmill-labs/windmill:1.767.0

# 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

# The file holds the database password: make it readable by its owner only
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'
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, o resultado pode conter +, / e =. Dentro de DATABASE_URL, esses caracteres precisam ser codificados com codificação percentual; sem essa codificação, podem comprometer a análise da URL e se manifestar como falhas de autenticação do PostgreSQL. Senhas hexadecimais dispensam completamente essa etapa de codificação.

Exemplo de senha problemática:

# Unless percent-encoded, the "/" in this password breaks DATABASE_URL:
PASSWORD="305t6m9KrChkvbyN/FLEYQ6pqAGlApn9rbJPH3D5y9g="

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 depois de receber as funções windmill_admin e windmill_user exigidas 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_PASSWORD quando volumes de dados existentes contêm credenciais diferentes
  • Formato da URL: Inclua ?sslmode=disable na URL do banco de dados quando ele estiver acessível apenas pela rede interna do Docker, como na configuração de exemplo do Windmill; use um modo SSL como require para 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: Redefinir o banco de dados exclui todos os dados do Windmill. Faça isso apenas em uma instalação nova ou após um backup verificado.

# WARNING: this deletes all Windmill data (fresh install or verified backup only)
cd /opt/windmill-pizza

# Stop containers
docker compose down --volumes

# Remove old data
rm -rf /opt/windmill-pizza/postgres-data/*

# Regenerate hex password and write it to both variables
NEW_PASSWORD=$(openssl rand -hex 16)
sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$NEW_PASSWORD/" .env
sed -i "s|^DATABASE_URL=postgresql://postgres:[^@]*@|DATABASE_URL=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
  • 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
umask 077

# docker compose needs the project directory, also when run from cron
cd /opt/windmill-pizza

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE=/opt/backups/windmill_pizza_${DATE}.sql
mkdir -p /opt/backups

if ! docker compose exec -T windmill-db pg_dump -U postgres windmill_pizza > "$BACKUP_FILE" || [ ! -s "$BACKUP_FILE" ]; then
  rm -f "$BACKUP_FILE"
  echo "Backup FAILED" >&2
  exit 1
fi
echo "Backup created: $BACKUP_FILE"
EOF

chmod +x /opt/windmill-pizza/backup.sh

Configurar monitoramento

cd /opt/windmill-pizza

# 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
set -euo pipefail
cd /opt/windmill-pizza

# Back up first; stop here if the backup fails
./backup.sh

# Pull and start the images set in .env (raise WM_IMAGE there to update Windmill)
docker compose pull
docker compose up -d
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
- [email protected]
# Only if your mail server requires authentication:
# - SMTP_USERNAME=...
# - SMTP_PASSWORD=...

Múltiplas instâncias do Windmill

Para equipes que necessitam de ambientes isolados:

# Create second instance from the configuration files only (not the data)
mkdir -p /opt/windmill-pasta/{postgres-data,windmill-data,lsp-cache}
cp /opt/windmill-pizza/{.env,docker-compose.yml,backup.sh,update.sh} /opt/windmill-pasta/
chmod 600 /opt/windmill-pasta/.env
cd /opt/windmill-pasta

# Update names, paths and domain
sed -i 's/pizza/pasta/g' .env docker-compose.yml backup.sh update.sh
sed -i 's/windmill.yourdomain.com/pasta.yourdomain.com/g' .env docker-compose.yml

# Generate new password and write it to both variables
NEW_PASSWORD=$(openssl rand -hex 16)
sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$NEW_PASSWORD/" .env
sed -i "s|^DATABASE_URL=postgresql://postgres:[^@]*@|DATABASE_URL=postgresql://postgres:$NEW_PASSWORD@|" .env

# Start the new instance
docker compose up -d

Considerações de segurança

Isolamento de rede

  • O PostgreSQL só pode ser acessado por contêineres na sua rede Docker; se essa rede for compartilhada com o proxy reverso e outros serviços, 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

cd /opt/windmill-pizza

# Container status
docker compose ps

# Resource usage
docker stats --no-stream

# Log analysis
docker compose logs | grep -i error

Manutenção mensal

# Back up and update containers (update.sh runs backup.sh first)
cd /opt/windmill-pizza
./update.sh

# Clean unused images, containers and networks
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, com um endereço IPv4 primário incluído (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: mais de $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

cd /opt/windmill-pizza

# 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 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 (under services: in docker-compose.yml)
windmill-worker-2:
  image: ${WM_IMAGE}
  container_name: windmill-pizza-worker-2
  restart: unless-stopped
  environment:
    - DATABASE_URL=${DATABASE_URL}
    - MODE=worker
    - WORKER_GROUP=heavy
  networks:
    - proxy
  depends_on:
    windmill-db:
      condition: service_healthy
  deploy:
    resources:
      limits:
        cpus: '2'
        memory: 4G

Escalabilidade vertical

Faça upgrade dos recursos do servidor (preços da Hetzner sem IVA, com um endereço IPv4 primário incluído 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
  • 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 do 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.

Da configuração à decisão operacional

A questão prática não é se uma plataforma pode ser configurada. É se a equipe consegue explicar quem é responsável, detectar desvios, recuperar o sistema sem improvisação e demonstrar que a alteração melhorou o resultado pretendido. Por isso, associamos cada mudança a um responsável, uma linha de base, um caminho de reversão e uma janela de verificação dos resultados. Isso transforma uma correção pontual em uma capacidade operacional. O registro de produção deve incluir o motivo da mudança, as evidências analisadas, o escopo exato e a pessoa autorizada a interrompê-la ou revertê-la. Após o lançamento, compare os indicadores acordados com a linha de base e mantenha o resultado junto ao registro da alteração. Se a melhoria esperada não ocorrer, a reversão é um resultado válido, e não um fracasso. Essa disciplina importa mais do que qualquer valor individual de configuração. O mesmo registro oferece ao próximo operador um ponto de partida confiável e torna a otimização posterior uma decisão baseada em medições, em vez de outra rodada de suposições.

Artigos relacionados

Leitura complementar