Skip to main content

Build | Docker

  • Build | Docker

Explicação sobre camadas | Docker

Untitled

  • O ponto inicial começa de uma imagem scratch, ela não muda, quando vamos executando os comandos nós vamos adicionando camadas

Tabela de Parâmetros do docker build

Flag curtaFlag longaDescriçãoExemplo
-t--tagDefine nome e tag da imagem-t app:1.0
-f--fileDefine o Dockerfile a ser usado-f Dockerfile.prod
--build-argPassa variáveis de build (ARG)--build-arg NODE_ENV=prod
--no-cacheDesativa completamente o cache--no-cache
--pullForça o pull da imagem base--pull
--targetBuilda um estágio específico (multi-stage)--target build
--platformDefine arquitetura/plataforma--platform linux/amd64
--progressDefine formato do output (auto, plain, tty)--progress=plain
--secretInjeta secrets no build (BuildKit)--secret id=npmrc,src=.npmrc
--sshForward de SSH para o build--ssh default
--labelAdiciona metadados à imagem--label version=1.0
-q--quietRetorna apenas o ID final da imagem--quiet
--rmRemove containers intermediários (default: true)--rm=false
--iidfileSalva o image ID em um arquivo--iidfile image.id

1. O que é o Docker Build?

O docker build é o comando responsável por criar imagens Docker a partir de um conjunto de instruções descritas em um Dockerfile. Essas imagens são artefatos imutáveis que contêm:

  • Um sistema de arquivos
  • Dependências
  • Binários
  • Configurações
  • Metadados

O processo de build pode ser entendido como uma pipeline de camadas, onde cada instrução do Dockerfile gera uma nova camada, que pode ser reutilizada futuramente via cache.


2. Estrutura Básica do Docker Build

O formato mais simples do comando é:

docker build -t minha-imagem:latest .

Onde:

  • docker build: executa o processo de build
  • -t: define nome e tag da imagem
  • .: define o build context

Esse comando aparentemente simples esconde uma enorme quantidade de possibilidades.


3. Build Context

O build context é o conjunto de arquivos enviados ao Docker daemon durante o docker build. Esse contexto define um limite rígido de acesso a arquivos.

Pontos importantes:

  • O Docker NÃO consegue copiar arquivos que estejam fora do diretório definido como build context
  • Arquivos localizados em diretórios pais (ex: ../arquivo.env) não podem ser acessados por COPY ou ADD
  • Isso é uma restrição de segurança, não uma limitação de sintaxe

Exemplo inválido:

COPY ../config.env /app/config.env

Esse comando falhará, pois o Docker não tem acesso a arquivos fora do contexto.

Boas práticas:

  • Organizar o projeto para que tudo que precisa ser copiado esteja dentro do contexto
  • Usar .dockerignore para excluir o que não deve ser enviado
  • Evitar contextos muito grandes por performance e segurança

4. Dockerfile: Possibilidades e Instruções

O Dockerfile é o coração do docker build. Abaixo estão as principais instruções e suas variações.

4.1 FROM

Define a imagem base.

FROM node:20-alpine

Possibilidades:

  • Imagens oficiais
  • Imagens customizadas
  • Imagens multi-stage

4.2 ARG

Permite passar variáveis em tempo de build.

ARG NODE_VERSION=20
FROM node:${NODE_VERSION}

Também pode ser usado via CLI:

docker build --build-arg NODE_VERSION=18 .

4.3 ENV

Define variáveis de ambiente persistentes na imagem.

ENV NODE_ENV=production

Diferença importante:

  • ARG: só existe no build
  • ENV: existe no runtime

4.4 RUN

Executa comandos durante o build.

RUN apt-get update && apt-get install -y curl

Cada RUN gera uma camada, o que impacta:

  • Cache
  • Tamanho da imagem

4.5 COPY e ADD

A instrução COPY é usada para copiar arquivos do build context para dentro da imagem.

COPY arquivo.txt /app/

Comportamento importante (muito confundido com o WORKDIR):

  • Se o diretório de destino NÃO existir, o Docker cria automaticamente
  • ❌ O Docker NÃO cria arquivos pai fora do contexto (restrição de segurança)
  • 📁 A criação automática vale apenas para diretórios de destino dentro da imagem

Exemplo válido:

COPY package.json /app/package.json

Mesmo que /app não exista, ele será criado.

Exemplo inválido:

COPY ../config.env /app/config.env

Esse comando falha porque o arquivo está fora do build context, não por causa do diretório de destino.

COPY vs ADD (resumo rápido)

  • COPY: simples, previsível, recomendado
  • ADD: cria diretórios também, mas adiciona comportamentos extras (extract, download) que podem causar efeitos colaterais

Boas práticas:

  • Use WORKDIR antes do COPY para clareza
  • Prefira COPY ao invés de ADD
  • Nunca confie em caminhos fora do build context

Exemplo recomendado:

WORKDIR /app
COPY . .

4.6 WORKDIR

A instrução WORKDIR define o diretório de trabalho padrão para todas as instruções seguintes (RUN, COPY, ADD, CMD, ENTRYPOINT).

WORKDIR /app

Comportamento importante (e comum de gerar confusão):

  • Se o diretório NÃO existir, o Docker o cria automaticamente
  • ❌ Não é necessário usar RUN mkdir /app
  • 🔁 Se WORKDIR for chamado múltiplas vezes, o caminho pode ser relativo ao anterior

Exemplo:

WORKDIR /app
WORKDIR logs

Resultado final:

/app/logs

Boas práticas:

  • Sempre usar WORKDIR antes de COPY e RUN
  • Evitar caminhos longos em um único comando quando a intenção for navegação progressiva
  • Não misturar WORKDIR com cd em RUN (o cd não persiste entre camadas)

Exemplo incorreto:

RUN cd /app
RUN npm install

Exemplo correto:

WORKDIR /app
RUN npm install

O WORKDIR melhora legibilidade, previsibilidade e reduz erros sutis durante o build.


4.7 EXPOSE

Documenta a porta usada pela aplicação.

EXPOSE 3000

Não publica a porta automaticamente.


4.8 CMD e ENTRYPOINT

Controlam o processo principal do container.

CMD ["node", "index.js"]

ou

ENTRYPOINT ["npm", "start"]

Podem ser combinados.


5. Multi-Stage Builds

Permite múltiplos FROM no mesmo Dockerfile.

FROM node:20 AS build
WORKDIR /app
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html

Vantagens:

  • Imagens menores
  • Mais segurança
  • Separação clara de responsabilidades

6. Cache de Build

O Docker reutiliza camadas se:

  • A instrução não mudou
  • Os arquivos envolvidos não mudaram

Opções:

docker build --no-cache .

Ou controle avançado com BuildKit.


7. BuildKit

BuildKit é o motor moderno de build.

Ativação:

DOCKER_BUILDKIT=1 docker build .

Possibilidades:

  • Builds paralelos
  • Cache remoto
  • Secrets
  • SSH forwarding

8. Secrets e SSH no Build

8.1 Secrets

docker build --secret id=npmrc,src=.npmrc .

No Dockerfile:

RUN --mount=type=secret,id=npmrc cat /run/secrets/npmrc

8.2 SSH

docker build --ssh default .

Usado para repositórios privados.


9. Plataformas e Arquiteturas

Build multi-arch:

docker buildx build --platform linux/amd64,linux/arm64 .

Muito usado para:

  • Apple Silicon
  • Cloud
  • IoT

10. Tags, Labels e Metadados

10.1 Tags

docker build -t app:1.0 -t app:latest .

10.2 Labels

LABEL maintainer="dev@empresa.com"
LABEL version="1.0"

Útil para:

  • Observabilidade
  • Compliance
  • Automação

11. Build a partir de Git

docker build https://github.com/user/repo.git

Ou com branch específica:

docker build https://github.com/user/repo.git#main

12. Buildx

docker buildx expande o build tradicional.

Funcionalidades:

  • Cache distribuído
  • Builders remotos
  • Multi-arch
  • Push direto para registry

Exemplo:

docker buildx build --push -t user/app:latest .

13. Boas Práticas Gerais

  • Use imagens base mínimas
  • Combine comandos RUN
  • Ordene instruções para maximizar cache
  • Use multi-stage
  • Evite secrets hardcoded
  • Use .dockerignore