{
 "grupo": "devops",
 "descricao": "DevOps, deploy e infraestrutura",
 "itens": [
  {
   "id": "devops-dockerfile-enxuto",
   "nome": "Dockerfile enxuto",
   "receita": "multi-stage, base slim fixada, dependências antes do código, usuário não-root",
   "prova": "docker images mostra o tamanho caindo e o container sobe sem root"
  },
  {
   "id": "devops-cache-de-camadas-no-build",
   "nome": "Cache de camadas no build",
   "receita": "copie o manifesto de dependências antes do código e use cache mounts do BuildKit",
   "prova": "segundo build sem mudança termina em segundos"
  },
  {
   "id": "devops-compose-para-desenvolvimento",
   "nome": "Compose para desenvolvimento",
   "receita": "serviços com healthcheck, depends_on condition, volumes nomeados e .env separado",
   "prova": "docker compose up deixa tudo saudável do zero"
  },
  {
   "id": "devops-escanear-a-imagem",
   "nome": "Escanear a imagem",
   "receita": "rode trivy ou grype na imagem, corrija as críticas atualizando base e pacotes",
   "prova": "relatório sem vulnerabilidade crítica"
  },
  {
   "id": "devops-pipeline-com-cache",
   "nome": "Pipeline com cache",
   "receita": "cache de dependências por hash do lockfile, jobs paralelos, falha rápida",
   "prova": "o pipeline cai de minutos para menos da metade"
  },
  {
   "id": "devops-pipeline-de-pull-request",
   "nome": "Pipeline de pull request",
   "receita": "lint, tipos, testes e build em paralelo; bloqueie merge sem verde; cancele execuções antigas da mesma branch",
   "prova": "PR com teste quebrado fica impedido de mesclar"
  },
  {
   "id": "devops-deploy-automatico-da-principal",
   "nome": "Deploy automático da principal",
   "receita": "build uma vez, promova a mesma imagem de staging para produção, com aprovação manual opcional",
   "prova": "a versão em produção tem o SHA do commit"
  },
  {
   "id": "devops-rollback-rapido",
   "nome": "Rollback rápido",
   "receita": "guarde as últimas versões; um comando volta à anterior; migrações compatíveis nos dois sentidos",
   "prova": "voltar a versão restaura o serviço em minutos"
  },
  {
   "id": "devops-deploy-sem-downtime",
   "nome": "Deploy sem downtime",
   "receita": "rolling ou blue-green com health check e conexões drenadas",
   "prova": "curl contínuo durante o deploy não perde nenhuma resposta"
  },
  {
   "id": "devops-canario",
   "nome": "Canário",
   "receita": "envie 5% do tráfego para a nova versão, compare erro e latência e só então promova",
   "prova": "métricas lado a lado antes de subir para 100%"
  },
  {
   "id": "devops-segredos-no-ci",
   "nome": "Segredos no CI",
   "receita": "use o cofre do provedor, escopo mínimo, nunca imprima, rotacione e prefira OIDC a chave longa",
   "prova": "o log não mostra o valor e a chave de longa duração sumiu"
  },
  {
   "id": "devops-variaveis-de-ambiente-por-ambiente",
   "nome": "Variáveis de ambiente por ambiente",
   "receita": "um arquivo de exemplo no repositório, valores no painel, validação na partida",
   "prova": "ambiente sem variável obrigatória falha ao subir"
  },
  {
   "id": "devops-infra-como-codigo",
   "nome": "Infra como código",
   "receita": "declare em Terraform, revise o plan no PR, estado remoto com trava, módulos pequenos",
   "prova": "plan sem mudança depois do apply (sem drift)"
  },
  {
   "id": "devops-dns-e-propagacao",
   "nome": "DNS e propagação",
   "receita": "confira A/AAAA/CNAME, TTL baixo antes da migração, e valide com dig em resolvedores diferentes",
   "prova": "dig +short retorna o IP novo em vários resolvedores"
  },
  {
   "id": "devops-certificado-tls-automatico",
   "nome": "Certificado TLS automático",
   "receita": "Let's Encrypt/ACME com renovação automática e alerta de vencimento",
   "prova": "openssl mostra validade acima de 30 dias e a renovação testada"
  },
  {
   "id": "devops-redirecionar-para-https",
   "nome": "Redirecionar para HTTPS",
   "receita": "redirect 301 no proxy, HSTS depois de confirmar que tudo é HTTPS",
   "prova": "curl -I em http devolve 301 para https"
  },
  {
   "id": "devops-proxy-reverso-nginx",
   "nome": "Proxy reverso nginx",
   "receita": "proxy_pass com cabeçalhos X-Forwarded, timeouts, gzip e nginx -t antes de recarregar",
   "prova": "a aplicação enxerga o IP real do cliente"
  },
  {
   "id": "devops-logs-centralizados",
   "nome": "Logs centralizados",
   "receita": "saída em stdout em JSON, coletor envia ao Loki/ELK/Datadog, retenção e busca por requestId",
   "prova": "buscar um erro encontra a linha em segundos"
  },
  {
   "id": "devops-alerta-que-importa",
   "nome": "Alerta que importa",
   "receita": "alerte por sintoma (erro, latência, saturação) com limiar e runbook; sem alerta que ninguém age",
   "prova": "incidente simulado dispara o alerta e o runbook resolve"
  },
  {
   "id": "devops-metricas-e-painel",
   "nome": "Métricas e painel",
   "receita": "exponha métricas (Prometheus), painel com as quatro de ouro por serviço",
   "prova": "painel mostra a requisição de teste nos gráficos"
  },
  {
   "id": "devops-orcamento-de-erro-e-slo",
   "nome": "Orçamento de erro e SLO",
   "receita": "defina SLO (99,9% de sucesso), meça com SLI e use o orçamento para decidir risco",
   "prova": "relatório mostra SLO atingido e o orçamento restante"
  },
  {
   "id": "devops-autoescala",
   "nome": "Autoescala",
   "receita": "escale por métrica real (CPU, fila, requisições), com mínimo, máximo e cooldown",
   "prova": "carga de teste cria réplicas e o recuo as remove"
  },
  {
   "id": "devops-limites-de-recurso",
   "nome": "Limites de recurso",
   "receita": "requests e limits de CPU e memória por serviço; observe OOMKilled e ajuste",
   "prova": "nenhum reinício por falta de memória sob carga"
  },
  {
   "id": "devops-rotina-de-backup",
   "nome": "Rotina de backup",
   "receita": "agende, criptografe, envie para fora do ambiente, monitore a falha e teste a restauração",
   "prova": "restauração em ambiente limpo concluída e medida"
  },
  {
   "id": "devops-rotacao-de-segredo",
   "nome": "Rotação de segredo",
   "receita": "gere novo, atualize o cofre, reinicie consumidores, revogue o antigo",
   "prova": "o serviço funciona com o novo e o antigo é recusado"
  },
  {
   "id": "devops-cron-confiavel",
   "nome": "Cron confiável",
   "receita": "caminho absoluto, PATH, saída para log, lock contra sobreposição e alerta de não execução",
   "prova": "o job roda no horário e a falha avisa"
  },
  {
   "id": "devops-runbook-de-incidente",
   "nome": "Runbook de incidente",
   "receita": "passos de diagnóstico por sintoma, quem chamar, como reverter e onde ver os logs",
   "prova": "alguém novo resolve o incidente simulado só com o runbook"
  },
  {
   "id": "devops-ambientes-de-preview",
   "nome": "Ambientes de preview",
   "receita": "cada PR sobe um ambiente efêmero com dados sintéticos e some ao fechar",
   "prova": "o link do PR abre a versão da branch"
  },
  {
   "id": "devops-monorepo-no-ci",
   "nome": "Monorepo no CI",
   "receita": "rode só o que mudou (turbo, nx, filtros de caminho) e cache por pacote",
   "prova": "mudar um pacote não roda os testes dos outros"
  },
  {
   "id": "devops-versionamento-e-changelog",
   "nome": "Versionamento e changelog",
   "receita": "versão semântica, tag por release e changelog gerado dos commits convencionais",
   "prova": "tag e notas geradas a cada release"
  },
  {
   "id": "devops-imagem-reproduzivel",
   "nome": "Imagem reproduzível",
   "receita": "fixe versões por digest, lockfile obrigatório e construa sem rede além do registro",
   "prova": "dois builds do mesmo commit geram o mesmo digest"
  },
  {
   "id": "devops-firewall-e-rede-privada",
   "nome": "Firewall e rede privada",
   "receita": "banco e filas só em rede privada; entrada só pelo proxy; portas mínimas abertas",
   "prova": "nmap de fora mostra só 80 e 443"
  },
  {
   "id": "devops-acesso-ssh-seguro",
   "nome": "Acesso SSH seguro",
   "receita": "só chave, sem senha, sem root, usuário nominal, bastion e logs de acesso",
   "prova": "tentativa com senha é recusada"
  },
  {
   "id": "devops-economia-de-custo-em-nuvem",
   "nome": "Economia de custo em nuvem",
   "receita": "etiquete recursos, desligue ambientes ociosos, defina orçamento e alerta",
   "prova": "relatório de custo por serviço e alerta configurado"
  },
  {
   "id": "devops-observar-o-deploy",
   "nome": "Observar o deploy",
   "receita": "marque a versão nos gráficos, compare erro antes e depois e tenha critério de rollback automático",
   "prova": "o painel mostra a linha do deploy e a regressão evidente"
  },
  {
   "id": "devops-migracao-de-hospedagem",
   "nome": "Migração de hospedagem",
   "receita": "replique, teste em paralelo, reduza TTL, troque DNS e mantenha a antiga até confirmar",
   "prova": "o tráfego vai ao novo sem perda de dados"
  },
  {
   "id": "devops-diagnosticar-container-que-reinicia",
   "nome": "Diagnosticar container que reinicia",
   "receita": "docker logs, inspect (ExitCode, OOMKilled) e rode com o mesmo comando em shell interativo",
   "prova": "causa identificada e container estável"
  },
  {
   "id": "devops-garantir-fuso-e-locale",
   "nome": "Garantir fuso e locale",
   "receita": "defina TZ e LANG na imagem; guarde tudo em UTC",
   "prova": "date no container bate com o esperado"
  },
  {
   "id": "devops-testar-o-pipeline-localmente",
   "nome": "Testar o pipeline localmente",
   "receita": "rode com act ou rode os mesmos comandos do job num container igual ao do CI",
   "prova": "o comando local reproduz o resultado do CI"
  }
 ]
}
