Jenkins Pipelines: o CI/CD da era enterprise
- ⬜🐙 GitHub Actions: CI/CD profissional do zero(DevOps & Containers)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
Jenkins é o avô do CI/CD e continua rodando metade da indústria. Nasceu em 2004 como Hudson, virou Jenkins em 2011, tem ~2.000 plugins e uma comunidade enorme. GitHub Actions e GitLab CI vieram depois, com sintaxe mais limpa e integração SaaS. Mas Jenkins sobrevive porque: roda on-prem em rede isolada, integra com qualquer coisa (SVN, Perforce, Bitbucket, sistemas legados), tem governança fina de permissões, e uma empresa de 20 anos provavelmente já tem 300 jobs investidos nele. Saber Jenkins é diferencial real em empresas de porte. Este guia cobre arquitetura moderna, Jenkinsfile declarativo, agents Kubernetes, shared libraries e migração de freestyle para pipeline-as-code.
Por que Jenkins ainda existe em 2026
Arquitetura: controller + agents
agent any apontando pro master). O controller carrega UI, schedule, gerencia estado — se o build consumir CPU/disco dele, a plataforma inteira engasga. Regra: controller não roda build. Nunca.Declarative vs Scripted Pipeline
| Critério | Declarative | Scripted |
|---|---|---|
| Sintaxe | Estrutura fixa: pipeline { }, agent, stages, steps, post | Groovy livre: node { } + steps imperativos |
| Validação | Linter oficial: jenkins-cli declarative-linter | Só roda no Jenkins pra saber se passa |
| Legibilidade | Alta — shape consistente entre projetos | Depende do autor |
| Poder | Suficiente pra 95% dos casos + escape hatch via script { } | Full Groovy — loops arbitrários, classes |
| Blue Ocean | Renderiza bem (grid de stages) | Renderização limitada |
| Uso recomendado | Default em 2026 | Só quando lógica for realmente dinâmica |
// Jenkinsfile — declarativo, 100 linhas cobrem um pipeline real
pipeline {
agent none // cada stage escolhe seu agent
options {
timeout(time: 30, unit: 'MINUTES')
timestamps()
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '20'))
}
environment {
IMAGE = "ghcr.io/me/api"
SHA = "${GIT_COMMIT.take(7)}"
}
stages {
stage('Checkout') {
agent { label 'linux' }
steps { checkout scm }
}
stage('Quality') {
parallel {
stage('Lint') {
agent { docker 'node:20-alpine' }
steps { sh 'npm ci && npm run lint' }
}
stage('Test') {
agent { docker 'node:20-alpine' }
steps { sh 'npm ci && npm test -- --ci' }
post { always { junit 'junit.xml' } }
}
}
}
stage('Build & push image') {
agent { label 'linux' }
when { branch 'main' }
steps {
withCredentials([usernamePassword(
credentialsId: 'ghcr',
usernameVariable: 'USER', passwordVariable: 'TOKEN')]) {
sh '''
echo "$TOKEN" | docker login ghcr.io -u "$USER" --password-stdin
docker buildx build --push --platform linux/amd64,linux/arm64 \
-t $IMAGE:$SHA -t $IMAGE:latest .
'''
}
}
}
stage('Deploy staging') {
agent { label 'kubectl' }
when { branch 'main' }
steps {
sh '''
kubectl set image deploy/api api=$IMAGE:$SHA -n staging
kubectl rollout status deploy/api -n staging --timeout=5m
'''
}
}
stage('Deploy prod') {
agent { label 'kubectl' }
when { branch 'main' }
input {
message 'Promote to production?'
ok 'Deploy'
submitter 'sre,tech-lead'
}
steps {
sh '''
kubectl set image deploy/api api=$IMAGE:$SHA -n prod
kubectl rollout status deploy/api -n prod --timeout=5m
'''
}
}
}
post {
success { slackSend channel: '#deploys', color: 'good', message: "✅ ${env.JOB_NAME} ${env.BUILD_NUMBER} deployed" }
failure { slackSend channel: '#deploys', color: 'danger', message: "❌ ${env.JOB_NAME} ${env.BUILD_NUMBER} failed" }
always { cleanWs() }
}
}Agents Kubernetes — o padrão moderno
Plugin kubernetes permite que o Jenkins agende agents como Pods efêmeros em um cluster K8s. Cada pipeline declara qual imagem quer; o Pod sobe, roda, morre. Escala automática, zero drift, custo sob demanda.
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: node
image: node:20-alpine
command: [cat]
tty: true
- name: docker
image: docker:26-dind
securityContext: { privileged: true }
- name: kubectl
image: bitnami/kubectl:1.30
command: [cat]
tty: true
'''
defaultContainer 'node'
}
}
stages {
stage('Install') { steps { sh 'npm ci' } }
stage('Test') { steps { sh 'npm test' } }
stage('Build') {
steps {
container('docker') {
sh 'docker build -t me/api:$GIT_COMMIT .'
}
}
}
stage('Deploy') {
steps {
container('kubectl') {
sh 'kubectl apply -f k8s/'
}
}
}
}
}Credentials — como não vazar segredo
stage('Deploy to AWS') {
steps {
withCredentials([[
$class: 'AmazonWebServicesCredentialsBinding',
credentialsId: 'aws-prod',
accessKeyVariable: 'AWS_ACCESS_KEY_ID',
secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
]]) {
sh 'aws s3 sync ./dist s3://meu-bucket --delete'
}
}
}Triggers e multibranch pipeline
| Tipo de job | O que cria | Quando usar |
|---|---|---|
| Pipeline (single) | Um job que lê Jenkinsfile de um branch | Raramente — só se repo tem 1 branch |
| Multibranch Pipeline | Descobre branches e PRs automaticamente, cria sub-job por branch | Default moderno |
| Organization Folder | Descobre TODOS os repos de uma org/user com Jenkinsfile | Empresas com 50+ repos |
| Freestyle | UI clicada, sem Jenkinsfile | Legado — não usar em projetos novos |
Blue Ocean + Pipeline Editor
Blue Ocean é a UI moderna do Jenkins: grid visual de stages, logs limpos, trace de falha direto. É um plugin (um pouco desatualizado em 2026 mas ainda útil). Alternativa: UI oficial nova do Jenkins 2.4xx também tem visual de pipeline.
Migração freestyle → pipeline
Performance e produção
Decisões
📋 Empresa nova, green field, tudo no GitHub
Jenkins é força desnecessária pra quem não tem drag de legado. GH Actions já resolve 95% dos casos com 10% do esforço operacional.
Alt: Jenkins — vire pra cá se crescer e precisar on-prem ou integração com sistemas exóticos.
📋 Banco/Seguradora com 500 jobs Jenkins, proibido SaaS, auditoria rigorosa
Migrar 500 jobs é projeto de meses. Modernizar sem trocar a plataforma dá retorno mais rápido: libraries padronizam, K8s agents resolvem escala, JCasC vira infra-as-code.
Alt: GH Actions Enterprise Server — se a empresa aceita investir na migração. Horizonte de 1-2 anos.
📋 Time pequeno, repo híbrido (GitHub + SVN legado), precisa CI dos dois
GH Actions nem enxerga SVN. Jenkins orquestra os dois, centraliza resultado, permite shared library comum.
Alt: Dois CIs separados — duplica overhead, fragmenta cultura.
Perguntas típicas
❓ Posso testar Jenkinsfile sem commitar 10 vezes?
jenkins-cli declarative-linter valida sintaxe. Replay na UI roda a mesma build com um Jenkinsfile editado sem commit. E JenkinsPipelineUnit permite teste unitário Groovy de shared library.❓ Como versionar a shared library?
@Library('lib@v1.2.0'); (2) branch — usa @Library('lib@main') para dev, tag em prod. Em ambiente regulado, pin por SHA é superior: @Library('lib@abc123def').❓ Jenkins em containers Docker no próprio Docker (DinD) — faz sentido?
❓ Como deploy de infra (Terraform) no Jenkins é diferente?
init → validate → plan → (approval) → apply. O plan vira artefato; apply usa exatamente esse plan com -lock-timeout. Credenciais via OIDC/STS, estado no S3 com DynamoDB lock. Um webhook por repo de infra.❓ Como cuidar de flakiness em testes E2E no Jenkins?
retry(2) em stages sabidamente flaky; (2) dashboard de flaky tests via Allure/Test Analytics; (3) quarentena — testes instáveis vão pra um stage que não falha o build, mas gera alerta. Corrigir a raiz é melhor que retry, mas retry salva deploy de sexta.Quiz rápido
4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito