Docker e JavaScript: conteinerização de aplicações Node.js (nível avançado)

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

Introdução: do simples ao complexo no mundo da conteinerização

\n\n

No nível inicial, trabalhar com Docker e JavaScript (Node.js) muitas vezes se resume a criar um Dockerfile simples e executar um contêiner. No entanto, em sistemas de produção reais, isso não é suficiente. O nível avançado implica uma compreensão profunda dos mecanismos de compilação, otimização do tamanho das imagens, gerenciamento de dependências, isolamento de rede e segurança.

\n\n

Neste artigo, abordaremos os principais aspectos da conteinerização profissional de aplicações Node.js. Você aprenderá como usar compilações em múltiplos estágios (multi-stage builds), configurar o Docker Compose para arquitetura de microsserviços, gerenciar variáveis de ambiente e minimizar a superfície de ataque. O material é voltado para desenvolvedores que já conhecem os fundamentos do Docker e JavaScript.

\n\n

1. Compilação em múltiplos estágios (Multi-stage builds) para Node.js

\n\n

Um dos principais problemas ao conteinerizar aplicações Node.js é o tamanho excessivo da imagem final. A abordagem padrão com um único Dockerfile inclui ferramentas de compilação (TypeScript, Webpack, Babel) que não são necessárias em tempo de execução. A compilação em múltiplos estágios permite dividir o processo em etapas: compilação e execução.

\n\n

1.1. Exemplo de Dockerfile com dois estágios

\n\n
# Estágio de compilação (build)\nFROM node:20-alpine AS builder\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY . .\nRUN npm run build  # Presume-se que o script build compila o projeto\n\n# Estágio de execução (production)\nFROM node:20-alpine AS production\nWORKDIR /app\n# Copiamos apenas node_modules e arquivos compilados\nCOPY --from=builder /app/node_modules ./node_modules\nCOPY --from=builder /app/dist ./dist\nCOPY package*.json ./\n\nEXPOSE 3000\nUSER node\nCMD ["node", "dist/index.js"]
\n\n

Pontos-chave:

\n
    \n
  • node:20-alpine — imagem leve baseada em Alpine Linux (cerca de 30 MB).
  • \n
  • npm ci — instalação limpa de dependências estritamente de acordo com package-lock.json.
  • \n
  • --only=production — excluímos dependências de desenvolvimento (TypeScript, testes).
  • \n
  • USER node — abandono do usuário root por segurança.
  • \n
\n\n

Como resultado, a imagem final contém apenas os arquivos necessários para a execução, e o tamanho é reduzido de 300-400 MB para 80-120 MB.

\n\n

1.2. Otimização do cache de camadas

\n\n

O Docker armazena em cache cada camada (comando). Para acelerar compilações repetidas, copie package*.json antes de copiar todo o código-fonte. Se as dependências não mudaram, a camada com npm ci será obtida do cache.

\n\n
COPY package*.json ./\nRUN npm ci --only=production\nCOPY . .  # Copiado apenas se o código-fonte mudou
\n\n

2. Docker Compose para arquitetura de microsserviços

\n\n

Em produção, uma aplicação Node.js raramente funciona isoladamente. Geralmente, são necessários um banco de dados (PostgreSQL, MongoDB), cache (Redis) ou fila de mensagens (RabbitMQ). O Docker Compose permite descrever toda a infraestrutura em um único arquivo YAML.

\n\n

2.1. Exemplo de docker-compose.yml para Node.js + Redis

\n\n
version: '3.8'\nservices:\n  app:\n    build:\n      context: .\n      dockerfile: Dockerfile.prod\n    ports:\n      - "3000:3000"\n    environment:\n      - NODE_ENV=production\n      - REDIS_URL=redis://redis:6379\n    depends_on:\n      - redis\n    networks:\n      - backend\n\n  redis:\n    image: redis:7-alpine\n    ports:\n      - "6379:6379"\n    volumes:\n      - redis_data:/data\n    networks:\n      - backend\n\nvolumes:\n  redis_data:\n\nnetworks:\n  backend:\n    driver: bridge
\n\n

Aspectos importantes:

\n
    \n
  • Isolamento de rede: os serviços se comunicam através da rede interna backend. O Redis não fica acessível externamente (a menos que a porta seja exposta).
  • \n
  • Volumes nomeados: redis_data preserva

Blogs

Book Recommendations