Deploy de Node.js no Brasil: processo, Dockerfile e PostgreSQL
Prepare uma aplicação Node.js para rodar no Hangar: versão do runtime, comandos, Dockerfile, porta, banco e diagnóstico depois do deploy.
O framework define como você desenvolve. A publicação depende também da versão do Node, dos arquivos gerados no build, do comando que mantém o processo ativo e das dependências externas. Neste artigo, o objetivo é tornar essas escolhas verificáveis no Hangar.
Se você ainda não tem uma aplicação, comece pela API Node.js completa. O Dockerfile abaixo usa exatamente os arquivos desse exemplo.
Defina o contrato de execução
Anote quatro informações no README do repositório:
| Informação | Exemplo da API deste guia |
|---|---|
| Versão do runtime | Node.js 24 |
| Instalação | npm ci, com lockfile versionado |
| Build | Não necessário para os arquivos .mjs do exemplo |
| Início | npm start, executando server.mjs |
Uma aplicação TypeScript normalmente precisa gerar JavaScript antes de iniciar. Confirme que o comando de início aponta para um arquivo que o build realmente produziu. Evite usar o servidor de desenvolvimento como processo de produção.
No Hangar, conecte o repositório GitHub e escolha detecção por Railpack ou build por Dockerfile. A branch e a pasta de origem devem conter os arquivos esperados. Confira a configuração detectada e o resultado nos logs, especialmente em monorepositórios.
Um Dockerfile para a API do tutorial
Depois de gerar e versionar o package-lock.json, adicione:
FROM node:24-bookworm-slim
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY app.mjs server.mjs ./
USER node
EXPOSE 3000
CMD ["node", "server.mjs"]
Esse exemplo é específico para a API em JavaScript sem etapa de compilação. Para TypeScript ou um framework com build, inclua a compilação e copie seus artefatos; não use este arquivo como se todos os projetos tivessem a mesma estrutura. A imagem e suas variantes estão documentadas no repositório oficial de Node para Docker.
Adicione também .dockerignore:
.git
node_modules
.env
.env.*
*.dump
Com Docker disponível, valide o mesmo caminho antes de publicá-lo:
curl --version
docker build -t minha-api .
docker run --rm -p 3000:3000 minha-api
Abra http://localhost:3000/health e confira a resposta. EXPOSE documenta a porta; o mapeamento local é feito por -p. No Hangar, configure a porta do serviço para corresponder à da aplicação.
Porta e endereço de escuta
Use process.env.PORT para permitir configuração e um endereço como 0.0.0.0 para aceitar conexões IPv4 pelas interfaces do container.
Não é correto afirmar que app.listen(3000) sempre escuta apenas em localhost. O comportamento depende da API e do framework; no servidor Node, omitir o host utiliza um endereço não especificado, em IPv6 quando disponível ou em IPv4. A referência de server.listen descreve esse comportamento.
PostgreSQL e arquivos persistentes
Crie PostgreSQL no ambiente da aplicação e use os dados de conexão apresentados no painel. Configure a variável esperada pelo seu código, como DATABASE_URL, e evite imprimir a URL nos logs.
Dimensione o pool considerando todas as réplicas: três processos com dez conexões cada podem solicitar trinta conexões, além das usadas por migrações e administração. Isso é uma conta de configuração, não uma recomendação de tamanho para toda aplicação.
Planeje migrações de schema em uma etapa controlada. Executá-las em todo início de réplica pode causar concorrência; uma alteração destrutiva também pode impedir a versão anterior de funcionar. Teste a compatibilidade entre versões.
Uploads que precisam sobreviver ao processo exigem armazenamento persistente apropriado. Um volume não substitui uma cópia recuperável. O banco gerenciado do Hangar ainda não inclui backup, restauração ou recuperação pontual nativos; a rotina externa e seu teste precisam fazer parte da operação.
Meça depois de publicar
Acompanhe uso de CPU e memória, logs de erro e comportamento das rotas reais. Para avaliar latência, meça a experiência dos seus usuários e a comunicação entre aplicação, banco e serviços externos. A região brasileira, sozinha, não determina um tempo de resposta.
No Hangar, os ajustes de CPU, memória e réplicas são manuais e respeitam a capacidade compartilhada do workspace. Confira no painel como aplicar uma alteração ao serviço. Antes de aumentar réplicas, identifique estado guardado em memória, sessões locais e escrita em arquivos que dependam de uma única instância.
Use a página de Node.js como referência da stack e o guia de CI com GitHub Actions para validar mudanças antes do merge.