Dockerfile: anatomia
Cada instrução do Dockerfile é um passo de montagem da imagem, executado em ordem, uma vez.
Um Dockerfile é a receita que gera uma imagem: uma sequência de instruções, cada uma executada em ordem, uma vez, no momento do build — não em toda execução do container.
Dockerfile — app Next.js
FROM node:20-alpine
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
EXPOSE 3000
CMD ["pnpm", "start"]Instrução por instrução
o que cada linha faz
FROM imagem-base a partir da qual a sua é construída (aqui: Node 20 numa distro leve, Alpine)
WORKDIR define o diretório de trabalho dentro do container — todo comando depois roda a partir dali
COPY copia arquivo(s) da sua máquina pra dentro da imagem
RUN executa um comando DURANTE o build (ex.: instalar dependências) — vira parte da imagem
EXPOSE documenta qual porta o container escuta (não abre a porta sozinho — isso é o -p do "docker run")
CMD o comando que roda quando o CONTAINER inicia (não durante o build) — só pode haver um CMD por DockerfileA diferença entre RUN e CMD é a que mais confunde no começo: RUN acontece uma vez, na hora de construir a imagem (instalar dependência, compilar). CMD acontece toda vez que um container inicia a partir dessa imagem.
Exercício
Escreva um Dockerfile mínimo pra uma API Rails: imagem base ruby:3.3-slim, copia Gemfile/Gemfile.lock, roda bundle install, copia o resto do código, expõe a porta 3000 e inicia com rails server -b 0.0.0.0.