Deploy Node.js na VPS com PM2 e systemd

10 min de leitura Infraestrutura
Deploy Node.js na VPS com PM2 e systemd

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.

Compartilhar: Link copiado!
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