CZANIX
Tech Reference
Infra

DevOps & Cloud

CI/CD que funciona, Docker com critério, Kubernetes quando faz sentido e FinOps embutido desde o início. DORA Metrics como bússola — não como vaidade de slide.

"Em TI, tudo é nivelado pelo mais lento. O alicerce precisa ser feito da melhor maneira possível desde o início."

— Cesar Zanis
01

DORA Metrics — as 4 que importam

Google pesquisou 30.000 profissionais por 6 anos. Essas 4 métricas diferenciam times Elite de times Low. Use como diagnóstico, não como meta de OKR.

Deployment Frequency

> 1x por dia (Elite)vs< 1x por mês (Low)

Por que importa

Frequência alta = lotes pequenos = menor risco por deploy. Time que deploya 1x por mês está acumulando risco, não sendo cuidadoso.

Como melhorar

Reduza o tamanho dos lotes. Feature flags para desacoplar deploy de release.

Lead Time for Changes

< 1 hora (Elite)vs> 6 meses (Low)

Por que importa

Tempo entre commit e produção. Longo = feedback lento = problemas descobertos tarde. Não é velocidade por velocidade — é ciclo de aprendizado.

Como melhorar

Automatize stages. Elimine aprovações manuais desnecessárias. Teste em PR, não depois do merge.

Change Failure Rate

< 5% (Elite)vs> 46% (Low)

Por que importa

Porcentagem de deploys que causam incidente. Alto = qualidade de teste ruim ou escopo de mudança grande demais.

Como melhorar

Testes automatizados com cobertura real (não decorativa). Blue/green deployment. Rollback em < 5 minutos.

MTTR (Mean Time to Restore)

< 1 hora (Elite)vs> 6 meses (Low)

Por que importa

Quanto tempo para restaurar serviço após incidente. Mais importante que não cair é saber voltar rápido.

Como melhorar

Runbooks documentados. Alertas com contexto (não só "CPU alta"). Post-mortem sem blame após cada SEV-1.

02

CI/CD — pipelines que funcionam

Pipeline mínimo que funciona (GitHub Actions)

YAML
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Cache de dependências — reduz tempo em 60-70%
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run lint
      - run: npm run test -- --coverage

      # Upload de coverage — visibilidade sem esforço
      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4

      # Build e push da imagem Docker
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:latest
          cache-from: type=gha   # Cache de layer Docker entre runs
          cache-to: type=gha,mode=max

Dockerfile multi-stage — a diferença entre 1.2GB e 120MB

YAML
# Dockerfile multi-stage
# Stage 1: Build — tem tudo que precisa para compilar
FROM node:20-alpine AS builder
WORKDIR /app

# Copiar só package.json primeiro — cache eficiente
# Se o código muda mas as dependências não, esta layer é reutilizada
COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# Stage 2: Runtime — tem só o que precisa para rodar
FROM node:20-alpine AS runner
WORKDIR /app

# Usuário não-root — segurança básica
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# Copiar apenas o output do build
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

USER nextjs
EXPOSE 3000
ENV PORT=3000 NODE_ENV=production

# Health check — o orquestrador sabe quando reiniciar
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
  CMD wget -qO- http://localhost:3000/api/health || exit 1

CMD ["node", "server.js"]

# Resultado: imagem final ~120MB vs ~1.2GB sem multi-stage
03

FinOps — custo como feature, não como acidente

A maioria dos times descobre que está pagando 3x mais do que deveria quando chega a fatura do fim do mês. FinOps não é cortar custo — é gastar o certo no lugar certo.

01

Dimensione para o P90, não para o pico

A maioria das empresas superprovisionou para pico máximo que acontece 5% do tempo. Auto-scaling resolve o pico. Right-sizing resolve os outros 95%.

02

Spot/Preemptible para workloads sem estado

CI/CD, processamento em batch, workers de fila. Até 80% mais barato. A contrapartida é interrupção — design stateless absorve isso.

03

Reserved instances só para baseline comprovado

Reserve o que você tem certeza que vai usar. O risco de comprometer capacidade que você não usa supera o desconto em cenários de mudança rápida.

04

Tags de custo desde o início

Sem tags por serviço/time/ambiente, o billing vira uma caixa preta. Crie a política de tags antes de criar qualquer recurso. Retroagir é doloroso.

05

Budget alert antes de estourar, não depois

Configure alertas em 50%, 80% e 100% do budget. O alerta de 50% é o que importa — te dá tempo de agir sem urgência.

Kubernetes — o mais mal-aplicado da lista

K8s resolve problemas de orquestração em escala. Se você tem menos de 10 serviços, uma equipe de 5 pessoas e não está operando em múltiplos clouds simultaneamente, você provavelmente está adicionando complexidade sem justificativa.

Use quando: múltiplos serviços com ciclos de deploy independentes, necessidade de auto-scaling granular, equipe com experiência real em K8s.

Evite quando: monólito funcional, time pequeno, operação em cloud único, nenhum engenheiro de plataforma dedicado. Docker Compose + Cloud Run/ECS resolve 80% dos casos com 20% da complexidade.

Precisa de ajuda para estruturar CI/CD, reduzir custo cloud ou medir DORA no seu time?

Fale com o Nix →