Docker e TypeScript: conteinerização de aplicações para desenvolvedores

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 ao Docker e TypeScript: por que a conteinerização é necessária

O desenvolvimento web moderno é impensável sem ferramentas que garantam a uniformidade do ambiente. Docker tornou-se o padrão de facto para empacotar, entregar e executar aplicações. Em combinação com TypeScript — uma linguagem estritamente tipada que compila para JavaScript — a conteinerização oferece uma ferramenta poderosa para criar serviços escaláveis e confiáveis.

Por que conteinerizar uma aplicação TypeScript? Primeiro, resolve o problema "funciona na minha máquina". Segundo, simplifica a implantação em produção e CI/CD. Terceiro, permite isolar dependências e versões do Node.js. Neste artigo, vamos abordar como criar uma imagem Docker para uma aplicação TypeScript, configurar uma build multi-stage e usar docker-compose para desenvolvimento local.



Fundamentos do Docker para o desenvolvedor TypeScript

Antes de escrever código, vamos lembrar os conceitos básicos do Docker: image (imagem) — modelo para criar um container; container — instância em execução de uma imagem; Dockerfile — instrução para construir a imagem.

Para uma aplicação TypeScript em Node.js, precisaremos de:

  • Node.js runtime (geralmente a imagem node:18-alpine ou node:20-alpine para tamanho mínimo)
  • Instalação de dependências (npm install ou yarn install)
  • Compilação de TypeScript para JavaScript (tsc)
  • Execução da aplicação compilada

Vamos considerar um exemplo simples de aplicação TypeScript (arquivo src/index.ts):

import express from 'express';

const app = express();const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => { res.send('Hello from TypeScript + Docker!');});

app.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});

E o tsconfig.json:

{  "compilerOptions": {    "target": "ES2020",    "module": "commonjs",    "outDir": "./dist",    "rootDir": "./src",    "strict": true,    "esModuleInterop": true  },  "include": ["src"],  "exclude": ["node_modules", "dist"]}

Agora vamos criar o Dockerfile para esta aplicação.



Criando um Dockerfile para aplicação TypeScript

Um Dockerfile básico pode ser assim:

FROM node:18-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run build

FROM node:18-alpine AS runnerWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/package*.json ./COPY --from=builder /app/node_modules ./node_modulesEXPOSE 3000CMD ["node", "dist/index.js"]

Aqui é usado multi-stage build (build em múltiplos estágios). O primeiro estágio (builder) compila TypeScript para JavaScript, o segundo (runner) contém apenas o código compilado e as dependências de runtime. Isso reduz o tamanho da imagem final — os arquivos TypeScript fonte e as dependências de desenvolvimento não entram nela.

Importante: executamos npm ci (instalação limpa) em vez de npm install para reprodutibilidade e velocidade.



Otimizando o Dockerfile: cache de camadas

Docker armazena em cache cada camada (instrução). Para acelerar a build, copie arquivos que mudam raramente primeiro. Por exemplo, package.json e package-lock.json são copiados antes de todos os fontes, portanto, alterações no código não causam reinstalação de dependências.

Adicionalmente, pode-se adicionar um .dockerignore:

node_modulesdist.git*.md.gitignore.env

Isso impede que arquivos desnecessários entrem no contexto da build.



docker-compose para desenvolvimento local

Para facilitar o desenvolvimento local, use docker-compose.yml. Ele permite executar a aplicação com recarga automática (usando nodemon ou

Blogs

Book Recommendations