Noções Básicas de Docker
10 exemplos para containerizar uma API Node.js TypeScript em Node 24 LTS - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para containerizar uma API Node.js TypeScript em Node 24 LTS - 7 básicos e 3 intermediários.
mkdir node-api && cd node-api
npm init -y
npm pkg set type=module
npm install express@5
npm install -D typescript@5.6 tsx @types/express @types/nodePara padrões multi-estágio e hardening de imagem, veja Builds Multi-Estágio e Contêineres Não-Root.
FROM node:24-bookworm-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY dist ./dist
ENV NODE_ENV=production
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]npm ci usa o lockfile para instalações reproduzíveispackage*.json antes do código fonte para que as camadas de dependência sejam bem cacheadasUSER node executa o processo sem privilégios de root.dockerignorenode_modules
dist
.git
.env
.env.*
*.md
coverage
.vscode
Dockerfile*
docker-compose*.yml
docker build mais rápido.env para uma camada de imagemFROM node:24-bookworm-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY tsconfig.json ./
COPY src ./src
RUN npm run build
FROM node:24-bookworm-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
USER node
CMD ["node", "dist/main.js"]docker builddist/ e node_modules de produçãoPORT do Ambienteimport express from "express";
const app = express();
const port = Number(process.env.PORT ?? 3000);
app.get("/health", (_req, res) => {
res.json({ status: "ok" });
});
app.listen(port, "0.0.0.0", () => {
console.log(`listening on ${port}`);
});0.0.0.0 dentro de contêineres, não a 127.0.0.1PORTdocker build e docker rundocker build -t my-api:local .
docker run --rm -p 3000:3000 -e PORT=3000 my-api:local
curl http://localhost:3000/health-p 3000:3000 mapeia a porta do host para a porta do contêiner--rm remove o contêiner após a saída (bom para testes rápidos locais)-e localmente; use um gerenciador de segredos em produçãopackage.json para Docker{
"scripts": {
"build": "tsc",
"start": "node dist/main.js",
"docker:build": "docker build -t my-api:local .",
"docker:run": "docker run --rm -p 3000:3000 -e PORT=3000 my-api:local"
}
}npm run docker:build após os testes passaremstart como node simples, não tsx, em imagens de produçãoHEALTHCHECK no DockerfileHEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD node -e "fetch('http://127.0.0.1:' + (process.env.PORT||3000) + '/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"HEALTHCHECK/health rápido: sem chamadas de banco de dados (use /ready para isso)FROM node:24-bookworm-slim AS base
WORKDIR /app
COPY package*.json ./
FROM base AS dev
RUN npm ci
COPY . .
CMD ["npx", "tsx", "watch", "src/main.ts"]
FROM base AS prod
RUN npm ci --omit=dev
COPY dist ./dist
USER node
CMD ["node", "dist/main.js"]docker build --target dev -t my-api:dev .
docker build --target prod -t my-api:prod .tsx watch) e produção--target seleciona o estágio finaldevDependencies; o de produção nãodocker compose para Stack Local# compose.yml
services:
api:
build: .
ports:
- "3000:3000"
environment:
NODE_ENV: development
PORT: 3000
DATABASE_URL: postgres://postgres:postgres@db:5432/app
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5depends_on com condition: service_healthy evita race conditions na inicializaçãoFROM node:24-bookworm-slim@sha256:abc123def456...Use node:24-bookworm-slim (glibc) por padrão. Alpine (musl) quebra alguns módulos npm nativos. Veja Trade-offs Distroless & Alpine.
Sim, para depurar problemas de imagem. CI constrói imagens; desenvolvedores ainda se beneficiam de docker build e compose para testes de integração.
Ou em um estágio de build Docker ou em CI antes do docker build. Não envie tsx ou typescript em imagens de produção, a menos que você tenha um bom motivo.
Uma API Express slim geralmente tem de 150 a 250 MB. Se a sua tiver 800 MB+, audite as camadas com Otimização de Imagem.
Um processo por contêiner. Execute a API e os workers de background como Deployments separados para que você possa escalá-los e implantá-los independentemente.
Variáveis de ambiente de segredos do orquestrador (K8s Secrets, segredos de tarefas ECS, SSM). Nunca incorpore segredos em camadas de imagem. Veja ConfigMaps & Secrets.
devDependencies fora da produçãoUSER node/health vs /readyVersões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026