# O Que É um Multi-Stage Build? Imagens Menores, Saída Mais Limpa

> Um multi-stage build usa vários stages FROM para que as ferramentas de build fiquem fora da imagem final. Aprenda como funciona, com um exemplo, e por que reduz drasticamente o tamanho da imagem.

Source: https://latchkey.dev/pt/learn/ci-explained/what-is-a-multi-stage-build  
Updated: 2026-06-26

Um multi-stage build compila em um stage descartável e copia apenas o artifact finalizado para um stage final pequeno - então sua imagem entrega a saída, não os toolchains.

Ferramentas de build, compiladores e dependências de dev são necessárias para produzir um artifact, mas não para executá-lo. Um Dockerfile multi-stage permite usar um stage builder pesado e então iniciar um stage final novo e mínimo que contém apenas o que você entrega. O resultado é uma imagem dramaticamente menor e mais segura.

## A ideia central

Você declara múltiplos stages `FROM` em um único Dockerfile. Os stages iniciais fazem o trabalho pesado; o stage final começa limpo e usa `COPY --from=<stage>` para puxar apenas a saída compilada. Tudo o que ficou para trás nos stages iniciais é descartado.

## Um exemplo em Go

Stage um:
`FROM golang:1.22 AS build`
`WORKDIR /src`
`COPY . .`
`RUN go build -o app .`
Stage dois:
`FROM gcr.io/distroless/static`
`COPY --from=build /src/app /app`
`ENTRYPOINT ["/app"]`
A imagem final tem o binário e nada mais.

## Por que encolhe tanto as imagens

A imagem do toolchain do Go tem centenas de megabytes; a imagem distroless final tem poucos. Como apenas o artifact do `COPY --from` chega no stage final, todo aquele peso de build nunca é entregue.

## Outros ganhos

- Menos pacotes significa menos vulnerabilidades na imagem em execução.
- Secrets usados durante o build podem ficar no stage builder.
- Você pode ter como alvo múltiplos stages finais (ex.: test vs prod) a partir de um único arquivo.

## Multi-stage builds em CI

Multi-stage builds cacheiam cada stage, então passos de builder inalterados são pulados. Em runners gerenciados com caches aquecidos, o custoso stage de compilação é reaproveitado entre jobs, e apenas a cópia final re-executa.

## Applying this to your pipeline

- Measure before changing. Most CI optimisation targets the wrong step because the slow one is assumed rather than timed.
- Cache what is expensive to produce and cheap to validate, and key the cache to the exact tool version.
- Fail fast: run the cheapest checks that can reject a change first, so an expensive job never starts on code that cannot pass.
- Prefer determinism over speed when they conflict. A fast pipeline nobody trusts gets re-run, which is slower than a slow one that is believed.

## FAQ

### What is What is a Multi-Stage Build? smaller Images, cleaner output?

Build tools, compilers, and dev dependencies are needed to produce an artifact but not to run it. A multi-stage Dockerfile lets you use a heavy builder stage and then start a fresh, minimal final stage that contains only what you ship. The result is a dramatically smaller and safer image.

### The core idea?

You declare multiple FROM stages in one Dockerfile. Earlier stages do the heavy lifting; the final stage starts clean and uses COPY --from=<stage> to pull in just the compiled output. Everything left behind in earlier stages is discarded.

### A Go example?

Stage one: FROM golang:1.22 AS build WORKDIR /src COPY . . RUN go build -o app . Stage two: FROM gcr.io/distroless/static COPY --from=build /src/app /app ENTRYPOINT ["/app"] The final image has the binary and nothing else.

### Why it shrinks images so much?

The Go toolchain image is hundreds of megabytes; the final distroless image is a few. Because only the COPY --from artifact lands in the final stage, all of that build weight never ships.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
