Files
Allyson de Paula 07b7ee62d3 Workshop completo: aulas 08-10 com Talos, n8n e GitLab na Hetzner
Aula 08 - Cluster Kubernetes HA:
- Setup interativo com OpenTofu para Talos na Hetzner
- CCM, CSI Driver, Cluster Autoscaler, Metrics Server
- NGINX Ingress com LoadBalancer (HTTP/HTTPS/SSH)

Aula 09 - n8n na Hetzner:
- Deploy via Helm com PostgreSQL e Redis
- Suporte multi-tenant com add-client.sh
- Integração com Hetzner CSI para volumes persistentes

Aula 10 - GitLab na Hetzner:
- Setup agnóstico: CloudFlare (trusted proxies) ou Let's Encrypt
- Anti-affinity para distribuir webservice/sidekiq em nós diferentes
- Container Registry e SSH via TCP passthrough
- Documentação do erro 422 e solução com trustedCIDRsForXForwardedFor

Melhorias gerais:
- READMEs atualizados com arquitetura e troubleshooting
- Scripts cleanup.sh para todas as aulas
- CLAUDE.md atualizado com contexto do projeto
2025-12-31 17:57:02 -03:00
..

Aula 01 - O Problema: Apps que Travam mas Nao Morrem

Objetivo

Demonstrar uma limitacao comum em ambientes de producao: aplicacoes que param de responder mas continuam com o processo rodando. O Docker nao consegue detectar esse tipo de falha.

O Problema

Imagine uma aplicacao que:

  • Tem um memory leak que causa travamento
  • Entra em deadlock
  • Perde conexao com o banco e fica em loop infinito

O processo continua vivo, mas a aplicacao nao responde. O Docker ve o processo rodando e nao faz nada.

A Aplicacao "Bugada"

Nossa app Node.js simula esse comportamento:

// Apos MAX_REQUESTS, para de responder mas continua rodando
if (requestCount > MAX_REQUESTS) {
  console.log('App travado apos 3 requests');
  return; // Nao responde, mas processo vivo
}

Arquivos

aula-01/
├── docker-compose.yml   # Configuracao do container
├── app.js               # Aplicacao Node.js "bugada"
└── .env                 # MAX_REQUESTS=3

Comandos

# Iniciar a aplicacao
docker compose up

# Parar a aplicacao
docker compose down

Teste Pratico

  1. Inicie a aplicacao:

    docker compose up
    
  2. Faca 3 requests (funcionam normalmente):

    curl localhost:3000   # Req -> 1/3
    curl localhost:3000   # Req -> 2/3
    curl localhost:3000   # Req -> 3/3
    
  3. Faca mais um request (vai travar):

    curl localhost:3000   # Fica esperando para sempre...
    
  4. Observe os logs - a app diz que travou:

    App travado apos 3 requests
    
  5. O container continua rodando:

    docker ps   # Container esta "Up", mas nao responde
    

A Limitacao do restart: always

No docker-compose.yml temos:

restart: always

Isso reinicia o container apenas quando o processo morre. Como nossa app trava mas o processo Node.js continua rodando, o Docker nao faz nada.

Situacao Processo Docker reinicia?
App crasha (exit 1) Morto Sim
App trava (nosso caso) Vivo Nao

Healthcheck do Docker: Detecta mas Nao Resolve

Adicionamos um healthcheck no docker-compose.yml:

healthcheck:
  test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
  interval: 2s
  timeout: 2s
  retries: 2
  start_period: 5s

Apos a app travar, veja o status mudar para unhealthy:

docker ps
# STATUS: Up 1 minute (unhealthy)

Porem, o Docker apenas DETECTA o problema - nao reinicia o container!

O healthcheck serve para:

  • Monitoramento e alertas
  • Orquestradores externos tomarem acao
  • Load balancers removerem o container do pool

Mas sozinho, nao resolve o problema.

Proximo Passo

Na Aula 02, vamos resolver esse problema usando Kubernetes com Liveness Probes - verificacoes periodicas que detectam quando a aplicacao parou de responder E reiniciam o container automaticamente.