0 XP
Módulo 4 · Docker e Compose

Multi-stage e segurança de imagem

Avançado 45 min+25 XPDockerTrivyBuildKit

Objetivos desta aula

  • Separar build de runtime
  • Rodar como usuário não-root com filesystem read-only
  • Escanear vulnerabilidades

Multi-stage build resolve um conflito antigo: para compilar você precisa de compilador, dependências de dev e ferramentas; para rodar, precisa apenas do artefato. Com estágios separados, o resultado final contém somente o necessário — imagem menor, build mais rápido e superfície de ataque reduzida.

Segurança de container tem uma lista curta e obrigatória: usuário não-root, sem segredo embutido, base atualizada e fixada, filesystem read-only quando possível, capabilities descartadas e limites de recurso definidos. Cada item desses aparece em checklist de auditoria real.

Scan de imagem no pipeline transforma segurança em processo. Falhe o build em vulnerabilidade crítica com correção disponível e gere SBOM para saber o que existe dentro do artefato — exigência crescente em contratos corporativos.

1. Multi-stage: build pesado, runtime enxuto

O primeiro estágio tem compiladores e dependências de desenvolvimento; o último copia só o resultado. Uma imagem Node cai de ~1 GB para ~150 MB, com menos superfície de ataque.

2. Imagens base mínimas

Alpine, slim e distroless reduzem pacotes (e vulnerabilidades). Distroless nem tem shell, o que dificulta invasores e também o debug — use kubectl debug ou imagens :debug quando necessário.

3. Não rode como root

Use USER node (ou um UID numérico). Se o processo for comprometido, o estrago fica limitado. Em Kubernetes, reforce com runAsNonRoot e readOnlyRootFilesystem.

4. Scan de vulnerabilidades e SBOM

Trivy ou Grype listam CVEs por severidade. Falhe o pipeline em CRITICAL com correção disponível. Gere um SBOM (lista de componentes) para responder rápido quando surgir uma nova CVE.

5. Checagem final

Sua imagem deve ser multi-stage, não-root, sem CVEs críticas corrigíveis e menor que 200 MB.

Na prática

Frontend Vue em multi-stage com Nginx

dockerfile

FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build          # gera /app/dist

FROM nginx:1.27-alpine AS runtime
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/app.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
USER nginx
CMD ["nginx", "-g", "daemon off;"]

Scan, SBOM e execução endurecida

bash

DOCKER_BUILDKIT=1 docker build -t cloudshop-web:v1 .
docker images cloudshop-web:v1 --format '{{.Size}}'

trivy image --severity HIGH,CRITICAL --exit-code 1 cloudshop-web:v1
docker sbom cloudshop-web:v1 2>/dev/null | head

docker run -d --name web \
  --read-only --tmpfs /tmp --tmpfs /var/cache/nginx \
  --cap-drop ALL --security-opt no-new-privileges \
  --memory 256m --cpus 0.5 -p 8080:80 cloudshop-web:v1

docker history cloudshop-web:v1 | head   # confirme que nao ha segredo

Nota de segurança: docker history revela comandos de build. Se um segredo passou por ARG, considere-o comprometido e rotacione.

Multi-stage não-root

dockerfile

FROM node:20.15-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --omit=dev

FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
USER 1000                          # nao-root
CMD ["dist/server.js"]

Scan e SBOM

bash

trivy image --severity CRITICAL,HIGH --ignore-unfixed --exit-code 1 cloudshop-api:1.4.0
trivy image --format cyclonedx -o sbom.json cloudshop-api:1.4.0
docker images cloudshop-api --format '{{.Tag}} {{.Size}}'

Por que isso importa

Imagem grande custa tempo de pipeline e dinheiro de registry; imagem insegura custa incidente.

Erro comum

Deixar devDependencies e ferramentas de build na imagem final.

Dica de produção

Use BuildKit com cache mount para dependências e mantenha a imagem final abaixo de 200 MB.

Alerta de segurança

Rodar como root com filesystem gravável permite que uma RCE na aplicação se torne persistente.

Pergunta de entrevista

Quais são as cinco medidas que você aplica para endurecer uma imagem de container?

Glossário

multi-stage
Dockerfile com vários FROM, copiando apenas artefatos entre estágios.
SBOM
Inventário dos componentes de software presentes no artefato.
distroless
Imagem sem gerenciador de pacotes nem shell, só o runtime necessário.
CVE
Identificador público de uma vulnerabilidade conhecida.
SBOM
Lista de todos os componentes e versões de um software.

Conexão com o CloudShop

Reduzir a imagem do frontend do CloudShop e bloquear o build em vulnerabilidade crítica.

Quiz da aula

  1. 1. Qual o principal benefício do multi-stage build?

  2. 2. Principal ganho do multi-stage?

  3. 3. Por que não rodar como root?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima