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
```html

Introdução: Por que a conteinerização avançada de TypeScript é uma necessidade

A conteinerização de aplicações TypeScript com Docker há muito deixou de ser apenas uma tendência — é o padrão do desenvolvimento moderno. No entanto, Dockerfiles básicos, que simplesmente copiam todo o projeto e executam npm start, estão longe do ideal. Em um nível avançado, enfrentamos desafios como otimização do tamanho das imagens, garantia de segurança, organização de arquitetura de microsserviços e configuração de recuperação automática.

Neste artigo, abordaremos técnicas que transformarão seu pipeline Docker para TypeScript em um padrão industrial: builds multi-estágio (multi-stage builds), minimização de camadas, uso de .dockerignore, Docker Compose para microsserviços, healthchecks e trabalho com variáveis de ambiente. Todos os exemplos são escritos em TypeScript e estão prontos para integração em projetos reais.

1. Build multi-estágio: do desenvolvimento à produção

O principal problema dos Dockerfiles básicos é que eles incluem tudo na imagem final: arquivos fonte, node_modules para desenvolvimento, ferramentas de build. Para TypeScript, isso é crítico, pois tsc e devDependencies não são necessários em produção.

O build multi-estágio (multi-stage build) resolve esse problema: o primeiro estágio compila e constrói o TypeScript, o segundo cria uma imagem mínima apenas com os arquivos necessários.

Exemplo de Dockerfile com dois estágios

# Estágio 1: Build do TypeScript
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY tsconfig.json ./
COPY src/ ./src/
RUN npm run build

# Estágio 2: Imagem de produção
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]

Pontos-chave:

  • Usamos npm ci — reprodução exata das dependências a partir do arquivo lock.
  • Copiamos apenas dist/ e node_modules — os arquivos fonte TypeScript não vão para produção.
  • Imagem Alpine — base mínima (cerca de 5 MB).

Essa imagem pesa de 3 a 5 vezes menos do que um build ingênuo. Para um projeto grande com dezenas de dependências, a diferença pode chegar a centenas de megabytes.

Build de três estágios com dependências de desenvolvimento

Às vezes, é necessário separar dependências de desenvolvimento e produção. Adicionamos um terceiro estágio para instalar apenas as dependências de produção:

# Estágio 1: Instalação de todas as dependências
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# Estágio 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Estágio 3: Produção
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=deps /app/node_modules ./node_modules
COPY package.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]

2. Otimização da imagem: .dockerignore, cache e camadas

Cada instrução COPY, RUN e ADD cria uma nova camada no Docker. Quanto menos camadas e mais eficientemente elas forem armazenadas em cache, mais rápida será a construção.

.dockerignore — seu primeiro aliado

Crie um arquivo .dockerignore na raiz do projeto:

node_modules
dist
.git
.gitignore
*.md
.env
.env.*
Dockerfile
.dockerignore
coverage
.vscode
.idea
__tests__

Isso impede a cópia de lixo para o contexto de build e acelera a transferência de arquivos para o daemon Docker.

Ordem correta das instruções

O Docker armazena camadas em cache. Se você copiar primeiro o package.json e depois executar npm ci, essa camada será reutilizada enquanto o package.json não mudar. Em seguida, copie o código fonte ```

Blogs

Book Recommendations