{"id":155,"date":"2019-12-05T16:19:00","date_gmt":"2019-12-05T19:19:00","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2019\/12\/devops-ci-cd\/"},"modified":"2026-10-05T13:45:45","modified_gmt":"2026-10-05T16:45:45","slug":"devops-ci-cd","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/es\/2019\/12\/devops-ci-cd\/","title":{"rendered":"DevOps: \u00bfqu\u00e9 es CI\/CD?"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro colocando uma caixa de container Docker na esteira de CI\/CD, entre a esta\u00e7\u00e3o do Git, o portal de testes e o rack Kubernetes, com o cachorro caramelo ao lado\" src=\"\/wp-content\/uploads\/2026\/10\/devops-cicd-v4.webp\" width=\"1486\" height=\"856\" \/><\/p>\n<div style=\"background:#fff8e1;border-left:4px solid #8b1a1a;padding:.8em 1em;margin:1em 0\"><strong>Nota (2026):<\/strong> Texto original de dezembro de 2019 \u2014 gloss\u00e1rio de CI\/CD ainda no vocabul\u00e1rio Jenkins\/Red Hat, com a nota \u201cvai ser melhorado em breve\u201d. Sete anos depois o YAML no Git virou o padr\u00e3o (GitHub Actions, GitLab CI, Forgejo\/Gitea Actions), o CD em Kubernetes virou GitOps (Argo CD \/ Flux) e o pr\u00f3prio pipeline passou a ser alvo de ataque \u00e0 cadeia de suprimentos. O conceito n\u00e3o mudou; a ferramenta e a amea\u00e7a, sim. <em>Revisado em 05\/10\/2026 com vers\u00f5es atuais e um diagrama do fluxo.<\/em><\/div>\n<p>CI\/CD n\u00e3o \u00e9 produto. \u00c9 o h\u00e1bito de <strong>integrar, testar e soltar software em ciclo curto<\/strong>, com o m\u00e1ximo de passos autom\u00e1ticos. O \u201cdia do merge\u201d de 2019 continua sendo o antipadr\u00e3o. O que mudou \u00e9 onde o YAML mora, quem roda o job e o que acontece <em>depois<\/em> que o pipeline fica verde.<\/p>\n<p><!-- more --><\/p>\n<h2>CI, entrega e implanta\u00e7\u00e3o \u2014 os tr\u00eas CDs<\/h2>\n<p><strong>CI (integra\u00e7\u00e3o cont\u00ednua):<\/strong> cada push ou merge request vira build e teste autom\u00e1ticos sobre o tronco compartilhado. O conflito aparece hoje, n\u00e3o na sexta-feira da release.<\/p>\n<p><strong>Entrega cont\u00ednua:<\/strong> o artefato aprovado (bin\u00e1rio, imagem OCI, pacote) vai sozinho para um registro e fica pronto para produ\u00e7\u00e3o. A subida ainda depende de um humano no bot\u00e3o \u2014 ou de um crit\u00e9rio: tag, aprova\u00e7\u00e3o, janela de mudan\u00e7a.<\/p>\n<p><strong>Implanta\u00e7\u00e3o cont\u00ednua:<\/strong> o mesmo artefato sobe sozinho para produ\u00e7\u00e3o se os testes passaram. O feedback do usu\u00e1rio chega em minutos. Exige testes em que voc\u00ea realmente confia, n\u00e3o um job verde oco.<\/p>\n<p>N\u00e3o vale brigar pelo acr\u00f4nimo. Vale desenhar o pipeline: o que \u00e9 autom\u00e1tico, o que \u00e9 porta e como se faz o rollback.<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/10\/devops-ci-cd-pipeline-gitops.webp\" alt=\"Diagrama do pipeline: desenvolvedor faz push, o runner de CI roda lint, testes, build e assinatura, envia a imagem ao registry e atualiza o reposit\u00f3rio GitOps; Argo CD ou Flux sincronizam o Kubernetes, e a observabilidade fecha o ciclo de feedback\" width=\"1200\" height=\"620\" \/><figcaption>O CI produz e assina o artefato; o CD leva o estado desejado do Git ao cluster; m\u00e9tricas e alertas devolvem o feedback.<\/figcaption><\/figure>\n<h2>O pipeline em 2026: YAML no Git<\/h2>\n<p>Jenkins com plugins ainda roda muito legado. O ponto de partida no Linux hoje \u00e9 um arquivo no reposit\u00f3rio, um runner em container e o artefato em um registry.<\/p>\n<p><strong>GitHub Actions<\/strong> \u2014 o padr\u00e3o de quem j\u00e1 est\u00e1 no GitHub. Fixe cada action pelo <em>SHA do commit<\/em>, n\u00e3o por tag flutuante: em mar\u00e7o de 2025 as tags da action <code>tj-actions\/changed-files<\/code> foram reapontadas para um commit malicioso que despejava secrets nos logs (<a href=\"https:\/\/www.cve.org\/CVERecord?id=CVE-2025-30066\">CVE-2025-30066<\/a>). Quem usava <code>@v45<\/code> rodou o c\u00f3digo do atacante; quem tinha fixado o SHA, n\u00e3o.<\/p>\n<pre><code class=\"language-yaml\"># .github\/workflows\/ci.yml\nname: ci\non:\n  pull_request:\n  push:\n    branches: [main]\npermissions:\n  contents: read\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n      - run: make test\n<\/code><\/pre>\n<p>O bloco <code>permissions<\/code> reduz o token do job ao m\u00ednimo necess\u00e1rio \u2014 sem ele, o padr\u00e3o pode ser mais amplo do que o teste precisa.<\/p>\n<p><strong>GitLab CI<\/strong> \u2014 o que o post irm\u00e3o de 2019 j\u00e1 usava para Terraform. Um <code>.gitlab-ci.yml<\/code> e runners pr\u00f3prios, se voc\u00ea quiser soberania:<\/p>\n<pre><code class=\"language-yaml\"># .gitlab-ci.yml\nstages: [test, image]\n\ntest:\n  stage: test\n  image: golang:1.27\n  script:\n    - go test .\/...\n\nimage:\n  stage: image\n  image: docker:29\n  services: [docker:29-dind]\n  script:\n    - echo \"$CI_REGISTRY_PASSWORD\" | docker login -u \"$CI_REGISTRY_USER\" --password-stdin \"$CI_REGISTRY\"\n    - docker build -t \"$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA\" .\n    - docker push \"$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA\"\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n<\/code><\/pre>\n<p>As vari\u00e1veis <code>CI_REGISTRY*<\/code> s\u00e3o preenchidas pelo pr\u00f3prio GitLab para o registry do projeto: nenhuma senha fica escrita no YAML.<\/p>\n<p><strong>Forgejo Actions \/ Gitea Actions<\/strong> \u2014 sintaxe compat\u00edvel em boa parte com o GitHub Actions, rodando self-hosted, sem mandar o c\u00f3digo para a nuvem alheia. O passo a passo com runner est\u00e1 no post sobre o <a href=\"\/2026\/09\/gitea-git-self-hosted-runner-tea\/\">Gitea com Actions e runner<\/a>. O Woodpecker \u00e9 a outra op\u00e7\u00e3o leve. No homelab Linux, isso compete com o GitLab CE.<\/p>\n<p>O <a href=\"\/2017\/08\/curso-de-docker-gratis\/\">curso de Docker<\/a> continua sendo pr\u00e9-requisito: o job moderno <em>\u00e9<\/em> um container. Infraestrutura como c\u00f3digo segue o mesmo esp\u00edrito: <a href=\"\/2026\/09\/automatizando-servidores-linux-com-ansible\/\">Ansible<\/a> e o pipeline de <a href=\"\/2019\/12\/terraform-pipelines-in-gitlab\/\">Terraform no GitLab<\/a>.<\/p>\n<h2>CD virou GitOps<\/h2>\n<p>Implantar no Kubernetes em 2026 raramente \u00e9 <code>kubectl apply<\/code> dentro do job de CI. O CI constr\u00f3i a imagem, assina, envia ao registry e <em>atualiza o Git<\/em> (tag ou digest). O cluster puxa o estado desejado:<\/p>\n<ul>\n<li><strong><a href=\"https:\/\/argo-cd.readthedocs.io\/\">Argo CD<\/a><\/strong> \u2014 aplica\u00e7\u00f5es declaradas no Git, detec\u00e7\u00e3o de drift e sincroniza\u00e7\u00e3o. A linha 3.5 (2026) trouxe mTLS no repo-server e uma verifica\u00e7\u00e3o opcional, ainda em alpha, da integridade das fontes no hydrator.<\/li>\n<li><strong><a href=\"https:\/\/fluxcd.io\/\">Flux<\/a><\/strong> \u2014 o outro projeto graduado da CNCF para GitOps, com controllers dentro do cluster.<\/li>\n<\/ul>\n<p>O Git passa a ser a fonte da verdade. O runner deixa de ter credencial de produ\u00e7\u00e3o eterna: OIDC para a nuvem, tokens de vida curta e admission no cluster verificando a assinatura (Cosign) antes do pod subir. Quem ainda faz <code>docker compose up<\/code> num VPS via SSH (como no <a href=\"\/2026\/09\/vaultwarden-bitwarden-self-hosted\/\">Vaultwarden<\/a>) est\u00e1 no degrau da entrega cont\u00ednua \u2014 v\u00e1lido, s\u00f3 n\u00e3o \u00e9 GitOps. Para o contexto de onde vieram as pe\u00e7as, veja <a href=\"\/2026\/09\/a-historia-do-docker\/\">a hist\u00f3ria do Docker<\/a> e <a href=\"\/2026\/09\/a-historia-do-kubernetes\/\">a do Kubernetes<\/a>.<\/p>\n<h2>O pipeline como alvo<\/h2>\n<p>Em 2019 o medo era o merge quebrado. Em 2026 o medo \u00e9 o job que <em>passa<\/em> e publica malware: action comprometida, pacote npm sequestrado, secret vazando no log.<\/p>\n<ul>\n<li>Fixe actions e imagens por SHA ou digest, nunca por <code>@v3<\/code> solto.<\/li>\n<li>Secrets no cofre (GitHub\/GitLab, Vault, SOPS) \u2014 nunca no YAML.<\/li>\n<li>Token do job com o m\u00ednimo de permiss\u00f5es (<code>permissions:<\/code> no Actions).<\/li>\n<li>SBOM e assinatura com <strong><a href=\"https:\/\/www.sigstore.dev\/\">Cosign<\/a><\/strong> (Sigstore, keyless via OIDC) na imagem.<\/li>\n<li>Proveni\u00eancia <strong><a href=\"https:\/\/slsa.dev\/\">SLSA<\/a><\/strong> Build L2\/L3 quando quem gera \u00e9 a plataforma de build, n\u00e3o um script do reposit\u00f3rio.<\/li>\n<li>PR vindo de fork: n\u00e3o rode o workflow do branch do atacante com secrets da organiza\u00e7\u00e3o (<code>pull_request_target<\/code> mal usado).<\/li>\n<\/ul>\n<p>Depois do deploy, o <a href=\"\/2026\/09\/monitorando-servidores-linux-com-prometheus\/\">Prometheus<\/a> diz se o verde mentiu.<\/p>\n<h2>Por onde come\u00e7ar de verdade<\/h2>\n<ol>\n<li>Tronco compartilhado, PRs pequenos, CI no PR (lint + teste). Sem isso, o resto \u00e9 teatro.<\/li>\n<li>Imagem OCI versionada pelo SHA do commit, em registry pr\u00f3prio ou no GHCR\/GitLab.<\/li>\n<li>Staging autom\u00e1tico; produ\u00e7\u00e3o com porta (tag ou aprova\u00e7\u00e3o) at\u00e9 os testes merecerem implanta\u00e7\u00e3o cont\u00ednua.<\/li>\n<li>S\u00f3 ent\u00e3o GitOps, assinatura e SLSA.<\/li>\n<\/ol>\n<p>Muita empresa para no passo 2 e chama isso de DevOps. N\u00e3o \u00e9 pecado; \u00e9 honesto. Pular para o Argo CD sem testes \u00e9 pintar o avi\u00e3o.<\/p>\n<p>Se o objetivo \u00e9 formalizar o conhecimento, o post sobre a <a href=\"\/2026\/09\/certificacao-lpi-devops\/\">certifica\u00e7\u00e3o LPI DevOps Tools Engineer<\/a> cobre CI\/CD, containers e automa\u00e7\u00e3o.<\/p>\n<h2>Uma volta visual<\/h2>\n<p>O epis\u00f3dio do <em>Dicion\u00e1rio do Programador<\/em>, do canal C\u00f3digo Fonte TV, resume pipeline e CI\/CD em poucos minutos:<\/p>\n<div style=\"position:relative;padding-bottom:56.25%;height:0;overflow:hidden;margin:1.5em 0\">\n<iframe src=\"https:\/\/www.youtube.com\/embed\/AZtTd3pFVTY\" title=\"Pipeline (CD\/CI) \/\/ Dicion\u00e1rio do Programador\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen style=\"position:absolute;top:0;left:0;width:100%;height:100%;border:0\"><\/iframe>\n<\/div>\n<h2>Refer\u00eancias<\/h2>\n<ul>\n<li><a href=\"\/2019\/12\/terraform-pipelines-in-gitlab\/\">Pipelines Terraform no GitLab<\/a> \u2014 o CD de infraestrutura no mesmo ano deste post<\/li>\n<li><a href=\"\/2026\/09\/gitea-git-self-hosted-runner-tea\/\">Gitea: Git self-hosted com Actions, runner e tea CLI<\/a><\/li>\n<li><a href=\"\/2026\/09\/a-historia-do-gitlab\/\">A hist\u00f3ria do GitLab<\/a><\/li>\n<li><a href=\"\/2017\/08\/curso-de-docker-gratis\/\">Curso de Docker gr\u00e1tis<\/a><\/li>\n<li><a href=\"\/2026\/09\/automatizando-servidores-linux-com-ansible\/\">Automatizando servidores Linux com Ansible<\/a><\/li>\n<li><a href=\"\/2026\/09\/monitorando-servidores-linux-com-prometheus\/\">Prometheus e Node Exporter<\/a><\/li>\n<li><a href=\"https:\/\/docs.gitlab.com\/ci\/\">GitLab CI\/CD docs<\/a> \u00b7 <a href=\"https:\/\/docs.github.com\/en\/actions\">GitHub Actions docs<\/a> \u00b7 <a href=\"https:\/\/forgejo.org\/docs\/latest\/user\/actions\/overview\/\">Forgejo Actions<\/a><\/li>\n<li><a href=\"https:\/\/slsa.dev\/\">SLSA<\/a> \u00b7 <a href=\"https:\/\/www.sigstore.dev\/\">Sigstore<\/a> \u00b7 <a href=\"https:\/\/argo-cd.readthedocs.io\/\">Argo CD<\/a> \u00b7 <a href=\"https:\/\/fluxcd.io\/\">Flux<\/a><\/li>\n<\/ul>\n<p>CI\/CD continua sendo o mesmo pipeline de 2019: integrar cedo, testar sempre, soltar em peda\u00e7os pequenos. O YAML foi para o Git, o cluster passou a puxar o estado, e o job verde agora precisa provar de onde veio o bin\u00e1rio. O resto \u00e9 ferramenta.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>CI\/CD no es un producto. Es el h\u00e1bito de integrar, probar y desplegar software en ciclos cortos, con el m\u00e1ximo de pasos automatizados. El \u201cd\u00eda del merge\u201d de 2019 sigue siendo el antipatr\u00f3n. Lo que cambi\u00f3 es d\u00f3nde vive el YAML, \u2026 <a title=\"DevOps: \u00bfqu\u00e9 es CI\/CD?\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/es\/2019\/12\/devops-ci-cd\/\" aria-label=\"Leer m\u00e1s sobre DevOps: o que \u00e9 CI\/CD?\">Leer m\u00e1s<\/a><\/p>","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[108,103,46],"tags":[105,106,9,47,156,48,49,517,104,518,225,519],"class_list":["post-155","post","type-post","status-publish","format-standard","hentry","category-ci-cd","category-cloud","category-devops","tag-ci-cd","tag-cloud","tag-dev","tag-devops","tag-docker","tag-git","tag-github","tag-github-actions","tag-gitlab","tag-gitops","tag-kubernetes","tag-supply-chain"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/155","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/comments?post=155"}],"version-history":[{"count":10,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/155\/revisions"}],"predecessor-version":[{"id":1779,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/155\/revisions\/1779"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/media?parent=155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/categories?post=155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/tags?post=155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}