Docker e TypeScript: conteinerização avançada de aplicações

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Docker e TypeScript: conteinerização avançada de aplicações

\n\n

A conteinerização de aplicações TypeScript com Docker não é apenas empacotar código em uma imagem. Em um nível avançado, é uma arte de otimização, segurança e automação. Neste artigo, vamos abordar como criar imagens Docker eficientes para TypeScript, gerenciar o ambiente e integrar a conteinerização no pipeline CI/CD. Você aprenderá como reduzir o tamanho da imagem em 5 a 10 vezes, acelerar a compilação e melhorar o isolamento de dependências.

\n\n

1. Compilação em múltiplas etapas (Multi-stage builds) para TypeScript

\n\n

O problema clássico das imagens Docker para TypeScript é incluir na imagem final todas as ferramentas de desenvolvimento: compilador TypeScript, dependências de desenvolvimento, arquivos fonte. Isso resulta em tamanhos enormes (frequentemente > 1 GB). A solução é a compilação em múltiplas etapas.

\n\n

A ideia é simples: o primeiro estágio (build) compila TypeScript para JavaScript e instala todas as dependências. O segundo estágio (production) copia apenas o JavaScript pronto e as dependências de produção.

\n\n
# Estágio 1: Compilação\nFROM node:20-alpine AS builder\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=development\nCOPY . .\nRUN npm run build\n\n# Estágio 2: Produção\nFROM node:20-alpine AS production\nWORKDIR /app\nCOPY --from=builder /app/dist ./dist\nCOPY --from=builder /app/package*.json ./\nRUN npm ci --only=production\nEXPOSE 3000\nCMD ["node", "dist/index.js"]
\n\n

Essa abordagem reduz o tamanho da imagem de ~800 MB para ~150 MB. Observe os --only=development e --only=production — são flags chave para separar as dependências.

\n\n

2. Otimização do cache de camadas do Docker

\n\n

Cada instrução no Dockerfile cria uma camada. O Docker armazena em cache as camadas se elas não forem alteradas. A ordem correta das instruções é crítica para a velocidade de compilações repetidas.

\n\n

Exemplo ruim (quebra o cache):

\n
FROM node:20-alpine\nWORKDIR /app\nCOPY . .\nRUN npm ci\nRUN npm run build\nCMD ["node", "dist/index.js"]
\n\n

Aqui, qualquer alteração no código fonte (mesmo no README.md) redefine o cache para npm ci e compilação.

\n\n

Exemplo bom (preserva o cache):

\n
FROM node:20-alpine AS builder\nWORKDIR /app\nCOPY package*.json tsconfig.json ./\nRUN npm ci --only=development\nCOPY src ./src\nRUN npm run build
\n\n

Por que isso funciona? As dependências mudam raramente, enquanto o código fonte muda frequentemente. Copiando package*.json separadamente, garantimos que a camada com npm ci seja reconstruída apenas quando esses arquivos forem alterados.

\n\n

3. Trabalho com variáveis de ambiente e segredos

\n\n

Para aplicações TypeScript em Node.js, o uso de variáveis de ambiente é padrão. No entanto, no Docker existem nuances.

\n\n

Erro típico: passar dados sensíveis (chaves de API, senhas) através de ENV no Dockerfile. Isso deixa segredos no histórico de camadas da imagem.

\n\n

Abordagem correta:

\n
    \n
  • Use --env-file ao iniciar o contêiner
  • \n
  • Para produção, utilize Docker Secrets (no Swarm) ou Kubernetes Secrets
  • \n
  • Para desenvolvimento local — arquivo .env com docker-compose
  • \n
\n\n

Exemplo de docker-compose.yml:

\n
version: '3.8'\nservices:\n  app:\n    build: .\n    ports:\n      - "3000:3000"\n    env_file:\n      - .env.production\n    volumes:\n      - ./logs:/app/logs
\n\n

No código TypeScript, use a biblioteca dotenv para carregar as variáveis:

\n
import dotenv from 'dotenv';\nimport { resolve } from 'path';\n\ndotenv.config({ path: resolve(__dirname, '../.env') });\n\nconst config = {\n  port: parseInt(process.env.PORT || '3000', 10),\n  dbUrl: process.env.DATABASE_URL,\n  apiKey: process.env.API_KEY\n};\n\nexport default config;
\n\n

Importante: nunca faça commit de arquivos .env reais

Blogs

Book Recommendations