Promover o mesmo artefato entre ambientes
O objetivo deste guia é simples de enunciar e frequentemente violado: o binário que roda em produção é exatamente o que passou nos testes. Um build por ambiente quebra isso, e o sintoma clássico é o bug que “só acontece em produção”.
1. Reconheça o problema de reconstruir por ambiente
Seção intitulada “1. Reconheça o problema de reconstruir por ambiente”Rebuildar para homologação e de novo para produção produz artefatos diferentes, mesmo com o mesmo commit: dependência transitiva que mudou de versão, imagem base atualizada, ordem de arquivos, cache que acertou de outro jeito. O teste validou um artefato; produção recebeu outro.
Além disso, o build de produção passa a ser o único que nunca foi exercitado antes de importar.
2. Construa uma vez e fixe o digest
Seção intitulada “2. Construa uma vez e fixe o digest”IMAGE="registry.exemplo.com/loja"docker buildx build --push -t "$IMAGE:${GIT_SHA}" .
# o digest é a identidade imutável do artefato; a tag é só um ponteiroDIGEST=$(docker buildx imagetools inspect "$IMAGE:${GIT_SHA}" \ --format '{{json .Manifest.Digest}}' | tr -d '"')echo "$DIGEST" # sha256:...Guarde o digest como saída do job e propague-o pelos estágios seguintes:
jobs: build: outputs: digest: ${{ steps.build.outputs.digest }} homologacao: needs: build uses: ./.github/workflows/deploy.yml with: { ambiente: hom, digest: "${{ needs.build.outputs.digest }}" } producao: needs: [build, homologacao] uses: ./.github/workflows/deploy.yml with: { ambiente: prod, digest: "${{ needs.build.outputs.digest }}" }No manifest, referencie por digest, nunca por tag móvel:
image: registry.exemplo.com/loja@sha256:SUBSTITUA_PELO_DIGEST_VALIDADOSe você usa tags para leitura humana, mantenha as duas: a tag descreve, o digest garante.
3. Tire a configuração de dentro da imagem
Seção intitulada “3. Tire a configuração de dentro da imagem”Se a imagem carrega a URL do banco de homologação, ela não pode ir para produção — e você volta ao build por ambiente. A separação:
- Na imagem: código, dependências, runtime. Nada específico de ambiente.
- Fora da imagem: variáveis, endpoints, limites, feature flags — em ConfigMap, parâmetros ou repositório de ambiente.
- Nunca em lugar nenhum do artefato: segredos, que vêm do cofre em tempo de execução.
# overlays/prod/kustomization.yaml — a diferença entre ambientes é este arquivoimages: - name: registry.exemplo.com/loja digest: sha256:SUBSTITUA_PELO_DIGEST_VALIDADOconfigMapGenerator: - name: loja-config literals: [LOG_LEVEL=info, TIMEOUT_MS=3000]Um teste útil: se você não consegue explicar por que a imagem de homologação não serviria para produção, ela serve — e deve ser promovida.
4. Deixe a promoção auditável
Seção intitulada “4. Deixe a promoção auditável”Promoção é uma decisão, e decisões precisam de registro. Em GitOps, o próprio pull request no repositório de ambiente é a trilha:
# o job de promoção altera uma linha e abre o PRyq -i '.images[0].digest = strenv(DIGEST)' overlays/prod/kustomization.yamlgit commit -am "promove loja ${GIT_SHA:0:7} para produção"gh pr create --title "Promover loja para produção" \ --body "Digest: $DIGEST — aprovado em homologação na execução #${RUN_ID}"O que o registro precisa responder depois: qual digest, quem aprovou, quando e com base em que evidência (testes verdes, canário estável). Ambientes protegidos do CI, com revisores obrigatórios, resolvem a parte de aprovação.
5. Verifique que o que subiu é o que foi aprovado
Seção intitulada “5. Verifique que o que subiu é o que foi aprovado”kubectl get deployment loja -n prod \ -o jsonpath='{.spec.template.spec.containers[0].image}' # deve conter o digest aprovado
# se você assina as imagens, verifique também a assinatura antes de promovercosign verify registry.exemplo.com/loja@sha256:SUBSTITUA \ --certificate-identity-regexp '^https://github.com/empresa/loja/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comMelhor ainda: torne isso uma política de admissão, para o cluster recusar imagem por tag ou sem assinatura, em vez de depender de disciplina.
Se der errado
Seção intitulada “Se der errado”| Sintoma | Causa provável |
|---|---|
| Produção rodando versão diferente da testada | Manifest com tag móvel em vez de digest |
| “Funciona em homologação” | Configuração dentro da imagem, ou dados diferentes |
| Digest não encontrado no registry | Retenção apagou a imagem — proteja as promovidas |
| Deploy sem mudança aparente | O digest não mudou: o build foi reproduzível, e está certo |
Checklist de pronto
Seção intitulada “Checklist de pronto”- Um único build por commit, com digest registrado.
- Todos os ambientes recebem o mesmo digest.
- Configuração e segredos fora da imagem.
- Promoção registrada com aprovador e evidência.
- Verificação pós-deploy compara o digest em execução com o aprovado.
- Política de admissão recusa tag móvel em produção.