Estrutura Básica

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "dist/main.js"]

Um Dockerfile simples para uma aplicação Node.js. Cada instrução cria uma layer na imagem.

FROM — Imagem Base

FROM node:22-alpine

Define a imagem base. Sempre prefira variantes Alpine para imagens menores.

FROM node:22-alpine AS builder

Nomeia o estágio para referência em multi-stage builds.

FROM ubuntu:24.04

Imagem Ubuntu completa quando precisar de mais pacotes do sistema.

FROM scratch

Imagem vazia, usada para binários compilados (Go, Rust) sem dependências.

FROM --platform=linux/amd64 node:22-alpine

Força a plataforma da imagem, útil para builds cross-platform.

WORKDIR — Diretório de Trabalho

WORKDIR /app

Define o diretório de trabalho para as instruções seguintes. Cria o diretório se não existir.

WORKDIR /app/backend

Pode ser usado várias vezes. Caminhos relativos são baseados no WORKDIR anterior.

COPY — Copiar Arquivos

COPY package*.json ./

Copia arquivos do contexto de build para a imagem. Suporta wildcards.

COPY . .

Copia todo o contexto de build para o WORKDIR atual.

COPY --chown=node:node . .

Copia definindo ownership dos arquivos diretamente.

COPY --from=builder /app/dist ./dist

Copia arquivos de outro estágio do multi-stage build.

COPY src/ ./src/
COPY tsconfig.json ./

Copia arquivos e diretórios específicos para controle granular de cache.

ADD — Copiar com Extras

ADD https://example.com/file.tar.gz /app/

Faz download de URLs e descompacta automaticamente arquivos tar.

ADD archive.tar.gz /app/

Descompacta o tar.gz automaticamente no destino.

Prefira COPY ao invés de ADD quando não precisar de download ou descompactação.

RUN — Executar Comandos

RUN npm ci

Executa comandos durante o build da imagem.

RUN npm ci --omit=dev

Instala apenas dependências de produção.

RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*

Agrupa comandos em um único RUN para reduzir layers. Sempre limpe cache do apt.

RUN --mount=type=cache,target=/root/.npm npm ci

Usa cache mount para acelerar builds subsequentes sem inflar a imagem.

RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci

Monta secrets temporariamente durante o build sem expor na imagem final.

CMD — Comando Padrão

CMD ["node", "dist/main.js"]

Define o comando padrão ao iniciar o container. Formato exec (recomendado).

CMD ["npm", "start"]

Alternativa usando npm como entrypoint.

CMD node dist/main.js

Formato shell — executa via /bin/sh -c. Menos eficiente, não recebe signals diretamente.

Apenas um CMD por Dockerfile. Se houver múltiplos, apenas o último é executado.

ENTRYPOINT — Ponto de Entrada

ENTRYPOINT ["node"]
CMD ["dist/main.js"]

ENTRYPOINT define o executável fixo, CMD fornece argumentos padrão substituíveis.

ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["start"]

Script de entrypoint que recebe ação como argumento.

ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]

Combinar ENTRYPOINT + CMD permite sobrescrever apenas os argumentos no docker run.

ENV — Variáveis de Ambiente

ENV NODE_ENV=production

Define variável de ambiente disponível no build e no runtime.

ENV NODE_ENV=production \
    PORT=3000 \
    LOG_LEVEL=info

Múltiplas variáveis em uma única instrução.

Para valores sensíveis (senhas, tokens), use --env no docker run em vez de ENV no Dockerfile.

ARG — Argumentos de Build

ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine

Variável disponível apenas durante o build. Pode ser sobrescrita com --build-arg.

ARG APP_VERSION=latest
ENV APP_VERSION=${APP_VERSION}

Combina ARG com ENV para persistir o valor no runtime.

docker build --build-arg NODE_VERSION=20 --build-arg APP_VERSION=1.2.0 .

Sobrescreve ARGs na linha de comando.

EXPOSE — Documentar Portas

EXPOSE 3000

Documenta que o container escuta na porta 3000. Não publica a porta automaticamente.

EXPOSE 3000 8080 443

Múltiplas portas em uma única instrução.

Para publicar a porta use -p 3000:3000 no docker run ou ports no Compose.

VOLUME — Pontos de Montagem

VOLUME /app/data

Cria ponto de montagem para dados persistentes.

VOLUME /app/uploads /app/logs

Múltiplos volumes em uma única instrução.

Prefira definir volumes no docker-compose.yml para maior controle sobre localização e drivers.

USER — Usuário de Execução

RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

Cria e usa um usuário não-root para segurança.

FROM node:22-alpine
USER node

Imagens oficiais do Node já incluem o usuário node.

Sempre execute containers como usuário não-root em produção.

HEALTHCHECK — Verificação de Saúde

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

Define como o Docker verifica se o container está saudável.

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD node -e "fetch('http://localhost:3000/health').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))"

Alternativa sem curl, usando apenas Node.js.

HEALTHCHECK NONE

Desabilita healthcheck herdado da imagem base.

LABEL — Metadados

LABEL maintainer="ivan@dev.com" \
      version="1.0.0" \
      description="API de produção"

Adiciona metadados à imagem. Útil para automação e documentação.

LABEL org.opencontainers.image.source="https://github.com/user/repo" \
      org.opencontainers.image.licenses="MIT"

Labels padronizados pela OCI (Open Container Initiative).

SHELL — Shell Padrão

SHELL ["/bin/bash", "-c"]
RUN echo "Agora usando bash"

Altera o shell usado para instruções RUN no formato shell.

SHELL ["powershell", "-Command"]
RUN Write-Host "Windows container"

Útil para containers Windows.

STOPSIGNAL

STOPSIGNAL SIGTERM

Define o signal enviado ao container para graceful shutdown. Padrão é SIGTERM.

Multi-Stage Build

Reduz drasticamente o tamanho da imagem final separando build e runtime.

FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY --from=builder /app/dist ./dist
COPY --from=deps /app/node_modules ./node_modules
COPY package*.json ./
USER appuser
EXPOSE 3000
CMD ["node", "dist/main.js"]

Três estágios: instalação de dependências, build e imagem final de produção.

Multi-Stage para Angular

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine AS runner
COPY --from=builder /app/dist/portfolio/browser /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Build do Angular e serve estático com Nginx. Imagem final tem apenas os arquivos compilados.

Multi-Stage para Angular SSR

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 4000
CMD ["node", "dist/portfolio/server/server.mjs"]

Para aplicações Angular com SSR, a imagem final precisa do Node.js para executar o servidor Express.

Multi-Stage para Go

FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags='-w -s' -o server ./cmd/server

FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
ENTRYPOINT ["/server"]

Imagem final FROM scratch — apenas o binário compilado. Resultado com poucos MB.

Multi-Stage para Java

FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

FROM eclipse-temurin:21-jre-alpine AS runner
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Separa build com Maven/JDK completo do runtime com apenas JRE.

.dockerignore

node_modules
dist
.git
.gitignore
.env
.env.*
*.md
!README.md
Dockerfile*
docker-compose*
.angular
.vscode
.idea
coverage
.nyc_output
*.log
tmp
temp

Exclui arquivos desnecessários do contexto de build. Reduz tempo e tamanho.

Otimização de Cache de Layers

Organize instruções da menos para a mais alterada:

FROM node:22-alpine
WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY tsconfig*.json ./
COPY src/ ./src/
RUN npm run build

Dependências mudam raramente e ficam no topo. Código-fonte muda frequentemente e fica por último.

FROM node:22-alpine
WORKDIR /app

COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \
    npm ci --prefer-offline

COPY . .
RUN npm run build

Cache mount do npm acelera rebuilds sem inflar layers da imagem.

Segurança

FROM node:22-alpine
WORKDIR /app

RUN apk add --no-cache dumb-init

ENV NODE_ENV=production
COPY --chown=node:node . .
RUN npm ci --omit=dev

USER node
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/main.js"]

Usa dumb-init para tratamento correto de signals e executa como usuário não-root.

FROM node:22-alpine
RUN apk update && apk upgrade --no-cache

Mantenha pacotes atualizados para patches de segurança.

FROM node:22-alpine@sha256:abc123...

Pin por digest garante builds reproduzíveis e protege contra imagens comprometidas.

Dockerfile para Python

FROM python:3.13-slim AS builder
WORKDIR /app
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.13-slim AS runner
WORKDIR /app
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY . .
USER nobody
EXPOSE 8000
CMD ["gunicorn", "app:create_app()", "-b", "0.0.0.0:8000"]

Multi-stage com virtualenv isolado para Python.

Dockerfile para Rust

FROM rust:1.84-alpine AS builder
WORKDIR /app
RUN apk add --no-cache musl-dev
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo 'fn main(){}' > src/main.rs && cargo build --release && rm -rf src
COPY src ./src
RUN cargo build --release

FROM scratch
COPY --from=builder /app/target/release/app /app
ENTRYPOINT ["/app"]

Pré-compila dependências em layer separada para cache eficiente.

Comandos Docker para Build

docker build -t minha-app .

Builda a imagem com tag minha-app usando o Dockerfile do diretório atual.

docker build -t minha-app:1.0.0 -f Dockerfile.prod .

Usa um Dockerfile alternativo e adiciona tag com versão.

docker build --target builder -t minha-app:debug .

Builda apenas até um estágio específico do multi-stage.

docker build --no-cache -t minha-app .

Builda sem usar cache de layers anteriores.

docker build --build-arg NODE_VERSION=20 -t minha-app .

Passa argumentos de build.

docker buildx build --platform linux/amd64,linux/arm64 -t user/app:latest --push .

Build multi-plataforma com Buildx e push direto para o registry.

Inspecionar Imagens

docker images

Lista todas as imagens locais.

docker image inspect minha-app

Mostra detalhes completos da imagem (layers, config, labels).

docker history minha-app

Mostra o histórico de layers e o tamanho de cada uma.

docker image prune -a

Remove todas as imagens não utilizadas.

Boas Práticas

  • Use imagens Alpine ou slim como base para reduzir tamanho
  • Aproveite multi-stage builds para separar build e runtime
  • Ordene instruções da menos para mais alterada para cache eficiente
  • Agrupe comandos RUN com && para reduzir número de layers
  • Use .dockerignore para excluir arquivos desnecessários do contexto
  • Execute como usuário não-root em produção
  • Não armazene secrets no Dockerfile — use --mount=type=secret ou variáveis no runtime
  • Prefira COPY sobre ADD quando não precisar de download ou descompactação
  • Use tags fixas em vez de latest para builds reproduzíveis
  • Defina HEALTHCHECK para monitoramento automático
  • Use dumb-init ou tini como init process para tratamento correto de signals
  • Mantenha imagens base atualizadas para patches de segurança
  • Minimize o número de layers combinando instruções relacionadas