Golden Images Docker: Por Que e Como Criar Imagens Base Padronizadas

Você já passou por aquela situação em que cada desenvolvedor do time usa uma imagem Docker diferente, com versões diferentes de pacotes, configurações diferentes de locale e timezone, e no final ninguém sabe por que a aplicação funciona na máquina de um e não na do outro? Pois é. Esse é exatamente o tipo de problema que uma Golden Image resolve.

Neste artigo, vamos entender o que é uma Golden Image, por que você deveria criar uma para o seu time, e como construir uma do zero — com exemplos práticos que você pode usar amanhã mesmo.

O Que é uma Golden Image?

Uma Golden Image (ou imagem dourada) é uma imagem Docker base, padronizada e aprovada, que serve como ponto de partida para todas as aplicações de um time ou organização.

Pense nela como o “molde oficial” que toda aplicação deve usar. Em vez de cada projeto começar de uma imagem diferente do Docker Hub e configurar tudo do zero, todos partem da mesma base — já com as configurações de segurança, locale, timezone e pacotes que a organização definiu como padrão.

Analogia Simples

Imagine uma fábrica de carros. Cada modelo é diferente, mas todos começam do mesmo chassi padronizado, testado e aprovado pela engenharia. A Golden Image é o chassi. Sua aplicação é o modelo específico que você constrói em cima dele.

Por Que Criar uma Golden Image?

1. Consistência entre Ambientes

Sem uma Golden Image, cada Dockerfile é um universo próprio. Um projeto usa debian:bullseye, outro usa ubuntu:22.04, outro usa bookworm-slim. Cada um configura timezone de um jeito, instala pacotes diferentes, cria usuários com IDs distintos.

Com uma Golden Image, todos os projetos compartilham a mesma base:

  • ✅ Mesmo sistema operacional e versão
  • ✅ Mesmo timezone e locale
  • ✅ Mesmo usuário não-root com os mesmos IDs
  • ✅ Mesmos pacotes base instalados

2. Segurança Centralizada

Quando uma vulnerabilidade é descoberta em um pacote do sistema operacional, você atualiza uma imagem e rebuild uma vez. Todos os projetos que herdam dela recebem a correção automaticamente no próximo build.

Sem Golden Image, cada projeto precisa ser atualizado individualmente — e inevitavelmente alguns vão ficar para trás.

3. Redução de Superfície de Ataque

Uma Golden Image bem construída instala apenas o mínimo necessário. Sem compiladores, sem ferramentas de debug, sem pacotes que “talvez alguém precise”. Menos pacotes = menos vulnerabilidades potenciais.

4. Onboarding Mais Rápido

Novos desenvolvedores não precisam entender como configurar locale, timezone, usuários e permissões no Docker. Tudo já está pronto na Golden Image. O Dockerfile da aplicação fica limpo e focado no que importa: a aplicação em si.

5. Governança e Compliance

Em ambientes regulados, ter uma imagem base aprovada e versionada facilita auditorias. Você pode provar que todas as aplicações rodam sobre uma base conhecida, testada e validada pelo time de segurança.

Anatomia de uma Golden Image

Uma boa Golden Image tem quatro pilares:

1
2
3
4
5
6
7
8
┌─────────────────────────────────────┐
│          Golden Image               │
├─────────────────────────────────────┤
│  1. Imagem base oficial             │
│  2. Configurações regionais         │
│  3. Pacotes mínimos necessários     │
│  4. Usuário não-root                │
└─────────────────────────────────────┘

Vamos construir uma passo a passo.

Construindo uma Golden Image na Prática

Escolhendo a Imagem Base

A primeira decisão é qual imagem base usar. Para aplicações .NET, a Microsoft oferece imagens oficiais. Para Python, a comunidade mantém imagens oficiais no Docker Hub.

Algumas dicas:

  • Use variantes slim — elas removem pacotes desnecessários (docs, man pages, etc.)
  • Prefira Debian/Ubuntu para produção — compatibilidade total com glibc, amplamente testadas
  • Evite Alpine em produção se sua stack depende de libs nativas — a musl pode causar incompatibilidades sutis
  • Fixe a versão da distro (ex: bookworm-slim, não apenas slim) — garante reprodutibilidade

Exemplo: Golden Image para ASP.NET 9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
FROM mcr.microsoft.com/dotnet/aspnet:9.0-bookworm-slim

LABEL maintainer="seu-email@empresa.com" \
      org.opencontainers.image.title="aspnet-net9.0-bookworm-slim" \
      org.opencontainers.image.version="1.0.0" \
      org.opencontainers.image.description="Imagem base para apps ASP.NET 9" \
      org.opencontainers.image.vendor="Sua Empresa" \
      org.opencontainers.image.licenses="Proprietary" \
      org.opencontainers.image.url="https://suaempresa.com"

# Configurações regionais
ENV TZ=America/Sao_Paulo \
    LANG=pt_BR.UTF-8 \
    LC_ALL=pt_BR.UTF-8 \
    ASPNETCORE_ENVIRONMENT=Production \
    DEBIAN_FRONTEND=noninteractive

# Instalação de pacotes
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        tzdata \
        locales && \
    echo "pt_BR.UTF-8 UTF-8" >> /etc/locale.gen && \
    locale-gen && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Usuário não-root
RUN groupadd -g 1001 appuser && \
    useradd -r --no-log-init -u 1001 -g appuser appuser

WORKDIR /app
EXPOSE 8080

USER appuser

Exemplo: Golden Image para Python 3.13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
FROM python:3.13-slim-bookworm

LABEL maintainer="seu-email@empresa.com" \
      org.opencontainers.image.title="python-3.13-bookworm-slim" \
      org.opencontainers.image.version="1.0.0" \
      org.opencontainers.image.description="Imagem base para apps Python 3.13" \
      org.opencontainers.image.vendor="Sua Empresa" \
      org.opencontainers.image.licenses="Proprietary" \
      org.opencontainers.image.url="https://suaempresa.com"

# Configurações regionais e Python
ENV TZ=America/Sao_Paulo \
    LANG=pt_BR.UTF-8 \
    LC_ALL=pt_BR.UTF-8 \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    DEBIAN_FRONTEND=noninteractive

# Instalação de pacotes
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        tzdata \
        locales && \
    echo "pt_BR.UTF-8 UTF-8" >> /etc/locale.gen && \
    locale-gen && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Usuário não-root
RUN groupadd -g 1001 appuser && \
    useradd -r --no-log-init -u 1001 -g appuser appuser

WORKDIR /app
EXPOSE 8000

USER appuser

Entendendo Cada Decisão

Vamos destrinchar o porquê de cada bloco:

Labels OCI:

1
2
LABEL org.opencontainers.image.title="..." \
      org.opencontainers.image.version="1.0.0"

Labels seguem o padrão OCI Image Spec. Eles documentam a imagem de forma padronizada — qualquer ferramenta que inspecione a imagem (Trivy, Docker Scout, etc.) consegue ler essas informações.

DEBIAN_FRONTEND=noninteractive:

Evita que pacotes como tzdata e locales parem o build para pedir input interativo. Sem isso, o build pode travar esperando uma resposta que nunca vai chegar.

--no-install-recommends:

O apt-get por padrão instala pacotes “recomendados” que você provavelmente não precisa. Essa flag instala apenas o estritamente necessário — reduzindo o tamanho da imagem e a superfície de ataque.

Limpeza do cache:

1
apt-get clean && rm -rf /var/lib/apt/lists/*

Remove o cache do apt da layer final. Sem isso, o cache de pacotes fica na imagem ocupando espaço à toa.

Usuário não-root:

1
2
RUN groupadd -g 1001 appuser && \
    useradd -r --no-log-init -u 1001 -g appuser appuser

Containers que rodam como root são um risco de segurança. Se um atacante explorar uma vulnerabilidade na aplicação, ele terá acesso root dentro do container — e potencialmente no host, dependendo da configuração. O --no-log-init evita problemas com logs de auditoria em containers.

IDs fixos (1001):

Usar IDs fixos (em vez de deixar o sistema gerar) garante consistência entre containers e facilita configuração de permissões em volumes compartilhados.

Como Usar a Golden Image nas Aplicações

Uma vez publicada no registry, a Golden Image é usada como FROM nos Dockerfiles das aplicações:

Aplicação ASP.NET

1
2
3
4
5
6
7
8
9
10
# Build stage — SDK padrão da Microsoft
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app/publish

# Runtime stage — sua Golden Image
FROM seu-registry.com/aspnet-net9.0-bookworm-slim:1.0.0
COPY --from=build --chown=appuser:appuser /app/publish .
ENTRYPOINT ["dotnet", "MinhaApp.dll"]

Aplicação Python (FastAPI)

1
2
3
4
5
6
7
8
# Sua Golden Image como base
FROM seu-registry.com/python-3.13-bookworm-slim:1.0.0

COPY --chown=appuser:appuser requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY --chown=appuser:appuser . .
ENTRYPOINT ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Repare como o Dockerfile da aplicação fica limpo e focado. Sem configuração de timezone, locale, pacotes base ou criação de usuário — tudo isso já vem pronto da Golden Image.

Build Multi-Plataforma

Se sua infraestrutura usa arquiteturas diferentes (por exemplo, estação de trabalho amd64 e servidor arm64), a Golden Image precisa suportar múltiplas plataformas.

A boa notícia: não precisa alterar o Dockerfile. O controle é feito no momento do build com docker buildx:

1
2
3
4
5
6
7
8
9
10
# Criar builder com suporte multi-plataforma
docker buildx create --name multiarch --use
docker buildx inspect --bootstrap

# Build para ambas as plataformas
docker buildx build \
    --platform linux/amd64,linux/arm64 \
    -f dockerfile.aspnet-net9.0-bookworm-slim \
    -t seu-registry.com/aspnet-net9.0-bookworm-slim:1.0.0 \
    --push .

O buildx resolve automaticamente a imagem base correta para cada arquitetura. O registry armazena um manifest list que aponta para as duas variantes, e o Docker do consumidor puxa a versão certa automaticamente.

Boas Práticas

Versionamento

  • 🏷️ Use versionamento semântico (SemVer) para suas Golden Images
  • 📌 Nunca use apenas latest — fixe a versão no FROM das aplicações
  • 📋 Documente o que mudou em cada versão (changelog)

Manutenção

  • 🔄 Rebuild periódico — mesmo sem mudanças no Dockerfile, faça rebuild mensal para incorporar patches de segurança da imagem base
  • 🔍 Scan de vulnerabilidades — use ferramentas como Trivy ou Docker Scout para verificar CVEs
  • 🧹 Limpeza de versões antigas — mantenha as últimas N versões e remova o resto

O Que Não Fazer

  • Não instale ferramentas de build (gcc, make, npm) na Golden Image de runtime
  • Não adicione código da aplicação — a Golden Image é só a base
  • Não use latest como tag da imagem base no FROM — fixe a versão da distro
  • Não rode como root — sempre defina um USER não-root

Quando Criar Variantes

Nem toda aplicação usa a mesma stack. É natural ter múltiplas Golden Images para diferentes runtimes:

Golden Image Base Uso
aspnet-net8.0-bookworm-slim Debian 12 Apps ASP.NET 8
aspnet-net9.0-bookworm-slim Debian 12 Apps ASP.NET 9
aspnet-net10.0-noble Ubuntu 24.04 Apps ASP.NET 10
python-3.12-bookworm-slim Debian 12 Apps Python 3.12
python-3.13-bookworm-slim Debian 12 Apps Python 3.13

O importante é manter o mesmo padrão entre todas: mesma estrutura de Dockerfile, mesmos IDs de usuário, mesmas labels OCI, mesma convenção de nomes.

💡 Dica: note que o .NET 10 usa Ubuntu (Noble) como base, não Debian (Bookworm). Nem sempre todas as variantes estarão disponíveis para todas as distros — valide no registry oficial antes de criar sua Golden Image.

Fluxo de Vida de uma Golden Image

1
2
3
4
5
6
7
8
9
10
┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│   Criação    │───▶│  Publicação  │───▶│    Uso       │
│  Dockerfile  │    │  no Registry │    │  pelas Apps  │
└──────────────┘    └──────────────┘    └──────────────┘
       │                                       │
       │            ┌──────────────┐           │
       └───────────▶│ Atualização  │◀──────────┘
                    │  (patches,   │
                    │   versões)   │
                    └──────────────┘
  1. Criação: time de DevOps/Plataforma define o Dockerfile padrão
  2. Publicação: build multi-plataforma e push para o registry privado
  3. Uso: times de desenvolvimento usam como FROM nos seus projetos
  4. Atualização: rebuilds periódicos para patches de segurança, novas versões

Conclusão

Uma Golden Image não é overhead — é investimento. O tempo gasto criando e mantendo uma base padronizada se paga rapidamente em:

  • 🔒 Menos vulnerabilidades para remediar
  • 🚀 Onboarding mais rápido para novos devs
  • 🎯 Dockerfiles de aplicação mais simples e focados
  • 📋 Auditorias e compliance facilitados
  • 🔄 Atualizações de segurança centralizadas

Comece com uma ou duas imagens para as stacks mais usadas no seu time, publique no seu registry privado e padronize o uso. Conforme a adoção cresce, expanda para outras stacks.

O chassi já está pronto. Agora é só construir os carros.


Referências:


Padronize a base, simplifique o topo. Seus deploys agradecem.

Happy Building! 🐳🏗️