Por que seu projeto JavaScript merece o Docker?
\n\nVocê já ouviu a frase: "Na minha máquina funcionava!"? Se você é um desenvolvedor JavaScript, provavelmente já enfrentou uma situação em que o aplicativo funciona perfeitamente localmente, mas no servidor ou no computador de um colega — falha com um erro misterioso. A containerização de aplicações JavaScript com Docker resolve esse problema de uma vez por todas.
\n\nO Docker permite empacotar seu código, todas as dependências (pacotes npm), variáveis de ambiente e até a versão do Node.js em um "contêiner" leve. Esse contêiner funcionará da mesma forma no seu notebook, no servidor AWS e no computador de um iniciante que acabou de instalar o Git. Neste artigo, vamos explorar como integrar JavaScript e Docker, escrever código real e criar uma imagem pronta para produção para o seu próximo pet-project.
\n\nFundamentos do Docker para desenvolvedores JavaScript
\n\nAntes de mergulhar no código, vamos entender os conceitos-chave. Docker é como uma máquina virtual, mas muito mais leve. Em vez de emular um sistema operacional inteiro, ele usa o kernel do host e isola apenas sua aplicação.
\n\nDockerfile — a receita da sua aplicação
\n\nEste é um arquivo de texto onde você descreve como construir a imagem. Para uma aplicação Node.js, um Dockerfile típico se parece com isso:
\n\n# Usamos a imagem oficial do Node.js\nFROM node:18-alpine\n\n# Definimos o diretório de trabalho dentro do contêiner\nWORKDIR /app\n\n# Copiamos package.json e package-lock.json\nCOPY package*.json ./\n\n# Instalamos as dependências\nRUN npm ci --only=production\n\n# Copiamos o código-fonte\nCOPY . .\n\n# Abrimos a porta\nEXPOSE 3000\n\n# Comando para iniciar\nCMD ["node", "server.js"]\n\nObserve: primeiro copiamos o package.json e depois todo o código. Isso não é por acaso. O Docker armazena em cache as camadas, e se você não alterou as dependências, a etapa npm ci não será reiniciada a cada alteração no código. Isso acelera muito a construção.
Imagens e contêineres
\n\n- \n
- Imagem (Image) — é um modelo. Você a constrói uma vez. \n
- Contêiner (Container) — é uma instância em execução da imagem. Você pode criar 10 contêineres a partir de uma única imagem. \n
Criando uma aplicação Node.js do zero e containerizando-a
\n\nVamos escrever uma aplicação Express simples e empacotá-la no Docker. Este será nosso primeiro passo prático na containerização de JavaScript.
\n\nPasso 1: Escrevendo a aplicação
\n\nCrie uma pasta docker-node-app e dentro dela, o arquivo server.js:
const express = require('express');\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\napp.get('/', (req, res) => {\n res.json({ \n message: 'Olá do contêiner!',\n nodeVersion: process.version,\n environment: process.env.NODE_ENV || 'development'\n });\n});\n\napp.listen(PORT, () => {\n console.log(`Servidor rodando na porta ${PORT}`);\n});\n\nInicialize o npm e instale o express:
\n\nnpm init -y\nnpm install express\n\nAgora temos uma aplicação funcional. Execute-a localmente: node server.js. Abra http://localhost:3000 — você verá um JSON.
Passo 2: Criando o Dockerfile
\n\nCrie um arquivo Dockerfile (sem extensão) na raiz do projeto:
FROM node:18-alpine\nWORKDIR /app\nCOPY package*.json ./\nRUN npm ci --only=production\nCOPY . .\nEXPOSE 3000\nCMD ["node", "server.js"]\n\nAdicione um .dockerignore para não copiar arquivos desnecessários para a imagem:
node_modules\nnpm-debug.log\n.git\n.gitignore\n.env\nDockerfile\n\nPasso 3: Construindo e executando
\n\nAbra o terminal na pasta do projeto e execute:
\n\ndocker build -t my-node-app .\ndocker run -p 3000:3000 my-node-app\n\nA flag