Deploy Node.js na VPS com PM2 e systemd

10 min de leitura Infraestrutura

Introdução ao Deploy Profissional de Aplicações Node.js

Levar uma aplicação Node.js do ambiente de desenvolvimento local para um servidor VPS (Virtual Private Server) em produção é um passo crítico que separa projetos amadores de infraestrutura profissional. Muitos desenvolvedores iniciantes cometem o erro de rodar a aplicação diretamente no terminal usando node app.js. Embora funcione, essa abordagem é insustentável: se você fechar o terminal ou sofrer uma queda de conexão, o processo morre. Além disso, não há gerenciamento automático de reinicialização em caso de falhas.

Neste tutorial técnico, vamos demonstrar a prática padrão da indústria para deploy linux de servidores Node. Utilizaremos duas ferramentas essenciais: o PM2, um process manager robusto que garante que sua aplicação permaneça online e reinicie automaticamente após erros ou reinicializações do servidor; e o systemd, o sistema de init do Linux, que gerencia o PM2 como um serviço nativo do sistema operacional. Essa combinação oferece alta disponibilidade, logs centralizados e controle total via comandos padrão do Unix.

Vamos assumir que você já possui acesso SSH à sua VPS com privilégios de root ou um usuário com permissões sudo. O ambiente alvo será uma distribuição Linux moderna, como Ubuntu 22.04 LTS ou Debian 12.

Etapas do Processo de Configuração

  1. Atualizar o Sistema Operacional: Garantir que todos os pacotes base estejam atualizados para evitar conflitos de dependências e vulnerabilidades de segurança.
  2. Instalar o Node.js e NPM: Configurar o ambiente de execução mais recente e estável (LTS).
  3. Preparar a Aplicação: Transferir os arquivos do projeto e instalar as dependências.
  4. Configurar o Gerenciador de Processos PM2: Iniciar a aplicação e gerar o script de inicialização.
  5. Integrar com Systemd: Criar uma unidade de serviço para gerenciar o PM2 como um daemon do sistema.
  6. Testar e Validar: Reiniciar o servidor e verificar se a aplicação sobe automaticamente.

Passo 1: Atualização do Sistema Operacional

A primeira medida de segurança e estabilidade é atualizar o repositório de pacotes da sua VPS. Isso garante que você esteja instalando versões compatíveis das ferramentas. Execute os comandos abaixo no terminal:

sudo apt update
sudo apt upgrade -y

O parâmetro -y automatiza a confirmação da instalação, mas em ambientes de produção sensíveis, considere remover esse flag para revisar as mudanças antes da instalação. Aguarde o término da operação.

Passo 2: Instalação do Node.js e NPM

Para garantir que você tenha a versão mais recente e estável do Node.js, utilizaremos o gerenciador de versões Node Version Manager (nvm). Esta é a abordagem recomendada porque permite alternar entre versões sem afetar outros projetos no servidor.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Após a instalação do script, você precisa recarregar as configurações do shell para que o comando nvm fique disponível na sessão atual:

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf '%s' "${HOME}/.nvm" || printf '%s' "${XDG_CONFIG_HOME-/etc/xdg}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

Agora, instale a versão LTS (Long Term Support) do Node.js. Esta é a versão recomendada para ambientes de produção:

nvm install --lts

Verifique as instalações para confirmar que tudo ocorreu corretamente:

node -v
npm -v

Você deve ver versões recentes exibidas no terminal. Se os comandos retornarem "command not found", feche e reabra o terminal SSH ou execute o comando nvm use --lts.

Passo 3: Preparação da Aplicação na VPS

Neste momento, precisamos transferir o código fonte da sua aplicação para a VPS. Você pode usar git se tiver um repositório remoto configurado, ou rsync/SCP para cópias diretas. Vamos assumir a abordagem via Git para manter a integridade do versionamento.

Crie um diretório dedicado para o projeto na VPS:

sudo mkdir -p /var/www/meu-app-node
cd /var/www/meu-app-node

Clone seu repositório. Se estiver usando SSH, certifique-se de que as chaves privadas tenham sido transferidas e configuradas corretamente:

git clone https://github.com/seu-usuario/seu-repositorio.git .

Agora, instale as dependências do projeto. É crucial usar --production para evitar instalar pacotes de desenvolvimento (devDependencies) que não são necessários em produção, economizando espaço e tempo:

npm install --production

Dica de Segurança: Nunca rode aplicações Node.js como usuário root. Crie um usuário dedicado para rodar a aplicação:

sudo adduser --disabled-password --gecos "" nodeapp
sudo chown -R nodeapp:nodeapp /var/www/meu-app-node

Passo 4: Configuração do Gerenciador PM2

O PM2 é o coração da nossa estratégia de alta disponibilidade. Ele mantém a aplicação viva, faz reloads sem downtime e centraliza os logs. Instale-o globalmente via NPM:

sudo npm install -g pm2

Antes de iniciar a aplicação, é boa prática criar um arquivo de configuração ecosystem.config.js. Isso permite definir variáveis de ambiente, memória máxima e políticas de reinicialização. Crie o arquivo na raiz do projeto:

cat > ecosystem.config.js << EOF
module.exports = {
  apps : [{
    name: "meu-app",
    script: "./app.js",
    instances: "max",
    exec_mode: "cluster",
    env: {
      NODE_ENV: "production",
      PORT: 3000
    },
    max_memory_restart: "1G"
  }]
}
EOF

Agora, inicie a aplicação com o PM2. Note que usamos o usuário nodeapp criado anteriormente para garantir a segurança:

sudo -u nodeapp pm2 start ecosystem.config.js

O PM2 irá exibir uma tabela com o status do processo. Verifique se ele está rodando com o comando:

pm2 list

Para que o PM2 sobreviva a reinicializações do servidor, precisamos gerar um script de inicialização específico para o sistema operacional atual:

sudo -u nodeapp pm2 startup systemd

O comando acima exibirá uma linha de comando longa. **Copie e execute exatamente essa linha** no terminal. Ela configura o PM2 para iniciar automaticamente quando o usuário nodeapp fizer login.

Passo 5: Integração com Systemd para Gerenciamento de Serviço

A etapa final e mais robusta é transformar o gerenciamento do PM2 em um serviço nativo do Linux. Isso nos permite usar comandos como systemctl start pm2-nodeapp. Para isso, salvamos o estado atual do processo:

sudo -u nodeapp pm2 save

Agora, precisamos criar uma unidade systemd personalizada. Crie um arquivo de serviço em /etc/systemd/system/pm2-nodeapp.service:

sudo nano /etc/systemd/system/pm2-nodeapp.service

Cole o seguinte conteúdo, ajustando os caminhos conforme necessário:

[Unit]
Description=PM2 instance manager service for meu-app nodejs
After=network.target

[Service]
Type=forking
User=nodeapp
Group=nodeapp
ExecStart=/usr/bin/pm2 start /var/www/meu-app-node/ecosystem.config.js --no-daemon
ExecReload=/usr/bin/pm2 reload all
ExecStop=/usr/bin/pm2 stop all
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Explicação Técnica:

  • Type=forking: Indica que o processo pai inicia e depois se desliga, deixando os filhos rodando.
  • User=nodeapp: Garante que o serviço rode com as permissões restritas do usuário dedicado.
  • Restart=always: Se o PM2 ou a aplicação falharem, o systemd tentará reiniciar o serviço automaticamente.

Salve o arquivo (Ctrl+O, Enter, Ctrl+X no nano). Agora, recarregue o daemon do systemd para reconhecer o novo serviço:

sudo systemctl daemon-reload

Habilite o serviço para iniciar na boot e inicie-o imediatamente:

sudo systemctl enable pm2-nodeapp
sudo systemctl start pm2-nodeapp

Passo 6: Validação e Monitoramento

Verifique se o serviço está ativo e saudável:

sudo systemctl status pm2-nodeapp

Você deve ver uma mensagem verde indicando "active (running)". Se houver erros, consulte os logs do systemd para diagnóstico:

journalctl -u pm2-nodeapp -e

Além disso, verifique se a aplicação Node.js está respondendo. Se você tiver um proxy reverso como Nginx configurado na porta 80 ou 443 para redirecionar o tráfego para a porta 3000 (ou a porta que sua app usa), teste via curl:

curl http://localhost:3000

Se a resposta for o conteúdo da sua aplicação ou um erro de rota configurada, mas sem crash do servidor, o deploy foi bem-sucedido.

Melhores Práticas para Administração de Sistemas Node.js

  • Logs: Nunca use console.log em produção para debug crítico. Utilize bibliotecas como winston ou pino e configure o PM2 para gerenciar o log rotation automaticamente com pm2 set pm2:log_date_format "YYYY-MM-DD HH:mm:ss".
  • Segurança: Mantenha suas dependências atualizadas. Use ferramentas como npm audit regularmente para identificar vulnerabilidades conhecidas.
  • Firewall: Bloqueie a porta da aplicação (ex: 3000) no firewall do servidor (UFW ou FirewallD). Permita apenas conexões vindas do seu proxy reverso (Nginx/Apache) ou de IPs específicos de monitoramento. O acesso público direto à porta Node deve ser negado.
  • Backups: Automatize backups do banco de dados e dos arquivos estáticos da aplicação. O código em si pode ser recuperado do Git, mas os dados são únicos.

Conclusão

Configurar um servidor Node.js com PM2 e systemd eleva significativamente a confiabilidade da sua infraestrutura. Ao invés de depender de sessões SSH voláteis, você possui um serviço gerenciado pelo kernel do Linux, capaz de se recuperar de falhas e reiniciar automaticamente após manutenções ou atualizações do sistema operacional.

Este setup é escalável e profissional, adequado para hospedar desde micro-serviços até aplicações web complexas. Com a base sólida estabelecida, você pode focar no desenvolvimento das funcionalidades da sua aplicação, tendo a tranquilidade de que o ambiente de produção está protegido e monitorado.

Lembre-se: a administração de sistemas é um ciclo contínuo de melhoria. Monitore o uso de CPU e memória através do painel do PM2 (pm2 monit) e ajuste os limites de recursos conforme o crescimento do seu tráfego.

Esse tutorial foi útil?

Comentários (0)

Seja o primeiro a comentar.

Deixe seu comentário

Seu comentário será analisado antes de ser publicado.

0/2000
WhatsApp