Job no Jenkins que “só o DevOps mexeu” é um rito, não um sistema. Alguém cola um shell de 80 linhas, um plugin de Docker, um SSH no final, e o time trata o botão verde como clima. Quando o verde some, ninguém sabe em que passo o software parou de ser o software.
Pipeline de entrega é uma sequência explicável. Build, teste, imagem, deploy. Cada passo tem entrada, saída e falha visível. Se você não consegue desenhar isso num quadro em três minutos, o risco não é o Jenkins. É o desconhecimento operacional disfarçado de automação.
O que a pipeline precisa ser
Integração contínua: cada mudança relevante passa pelo mesmo caminho. Entrega contínua: o caminho termina num artefato pronto (e, se o time quiser, num ambiente). O Jenkins é um orquestrador comum, não o único. A ferramenta importa menos do que a sequência ser a mesma para todo mundo — inclusive às 2h da manhã.
Passos típicos, nesta ordem, salvo motivo forte:
- Obter o código na revisão certa.
- Construir (dependências, assets, binário).
- Rodar testes e linters no mesmo contexto do build.
- Empacotar um artefato imutável (imagem Docker, pacote).
- Publicar o artefato.
- Implantar num ambiente, com aprovação se produção exigir.
Inverter teste e imagem “para ir mais rápido” produz imagem que nunca foi exercitada. Pular teste no job de produção porque “já rodou no de dev” produz drift: o job de prod não é o mesmo código de checagem. Dois jobs que não se falam são duas verdades.
Docker como build reproduzível
O problema clássico: “na minha máquina passa”. Python 3.10 aqui, 3.8 no servidor, lib de sistema diferente, locale diferente. Docker não resolve produto. Resolve o chão: o build acontece numa imagem conhecida, com Dockerfile versionado ao lado do código.
O Jenkins, nesse desenho, não instala a stack da aplicação no mestre. Dispara um agente — local, SSH, ou o próprio daemon Docker — que roda docker build, docker run para testes, publica a imagem. O mestre orquestra. O ambiente de build é o Dockerfile.
Hadolint no Dockerfile, testes na imagem de build, tag com o commit (não só latest): detalhes que separam “temos container” de “temos artefato rastreável”. latest que sobrescreve não é versão. É sorte.
Há um anti-padrão simétrico: Jenkins que constrói na mão (venv, pip install no agente) e só usa Docker no deploy. O agente vira pet. A pipeline vira a máquina do agente. Quando o agente morre, a receita morre. Se o build não cabe num Dockerfile, documente por quê. Quase sempre cabe.
flowchart TD
A[Commit] --> B[Jenkins]
B --> C[Build na imagem]
C --> D{Testes}
D -->|Falha| E[Para e avisa]
D -->|Passa| F[Imagem versionada]
F --> G[Registry]
G --> H[Deploy staging]
H --> I{OK?}
I -->|Não| E
I -->|Sim| J[Deploy produção]
classDef ouro fill:#FBF5E4,stroke:#C9A227,color:#0B1F18,stroke-width:1.4px
classDef verde fill:#F3FAF7,stroke:#1E7A57,color:#0B1F18,stroke-width:1.4px
classDef fim fill:#14513B,stroke:#0F3328,color:#FBFAF6,stroke-width:1.4px
class A,B ouro
class C,D,F,G,H,I verde
class E,J fim
Job que você não desenha é risco
Risco de conhecimento: só uma pessoa sabe que o passo 4 precisa da variável que está no “configure system” e não no repositório. Risco de segurança: credencial no job, SSH irrestrito, daemon Docker aberto em 0.0.0.0. Risco de produto: staging e produção divergem no script, então o teste de staging não testa o que sobe.
Pipeline como código (Jenkinsfile no repo) não é moda. É o desenho versionado junto da aplicação. Review de pipeline é review de como o software nasce. Plugin cliqueado na UI sem registro no repo é configuração oral.
Integração entre jobs — “o job de dev dispara o de prod” — precisa de contrato: mesmo artefato, não rebuild. Rebuild em produção a partir da branch “porque o job é outro” é como recompilar na sala do cliente. Promova a imagem que já passou no teste.
| Sintoma | O que esconde | Movimento |
|---|---|---|
| Só uma pessoa corrige o job | Receita fora do repo | Jenkinsfile + README do fluxo |
| Verde em dev, vermelho em prod | Dois scripts, dois mundos | Promover artefato, não rebuild |
latest em produção |
Impossibilidade de rollback | Tag com commit/sha |
| Teste no notebook, não no job | CI de fachada | Teste na mesma imagem do build |
| SSH root no final | Deploy irreproduzível | Imagem + pull no alvo |
O quadro de três minutos
Peça a qualquer pessoa do time, não só a quem “cuida do Jenkins”:
- O que dispara o fluxo?
- Onde o teste roda, em qual imagem?
- Qual é o artefato, e como ele é nomeado?
- Como staging recebe esse artefato?
- Como produção recebe o mesmo artefato?
- Como se volta a versão anterior?
Se a resposta a (6) for “sobe o job de novo e reza”, não há entrega contínua. Há botão. Rollback é puxar a tag anterior, não reconstruir a main de ontem com dependências de hoje.
Notificação (Slack, e-mail) é parte do desenho: quem precisa saber que o passo D falhou, com o link do log. Silêncio no vermelho treina o time a ignorar o CI.
Comece pelo fluxo, não pelo plugin
Instalar Jenkins, expor o daemon Docker e clicar em “Build and publish” é o tutorial. O trabalho é tornar a sequência visível, repetível e dona de um artefato. Docker entra porque o build deixa de ser a neve no servidor de CI. Jenkins entra porque alguém precisa encadear e registrar.
Quando o fluxo cabe num mermaid — e o mermaid deste texto deveria ser reconhecível no seu repo —, a ferramenta pode até mudar. GitHub Actions, GitLab, o que for. A pipeline que você explica sobrevive à ferramenta. A que você não explica já falhou, só ainda está verde.
A Programming One trata o caminho até produção como parte do livro, não como apêndice de DevOps: o projeto precisa sair do notebook.
Leia também: SRE: SLI, SLO e orçamento de erro e Nuvem não é compra de servidor.