Introdução
O Node.js é um ambiente de tempo de execução JavaScript de código aberto para construir aplicativos de servidor e de rede. A plataforma é executada no Linux, macOS, FreeBSD e Windows. Embora seja possível executar aplicativos Node.js na linha de comando, este tutorial se concentrará em executá-los como um serviço. Isso significa que eles serão reiniciados no reinício ou falha e são seguros para uso em um ambiente de produção.
Neste tutorial, você configurará um ambiente Node.js pronto para produção em um único servidor Rocky Linux 9. Este servidor executará um aplicativo Node.js gerenciado pelo PM2 e fornecerá aos usuários acesso seguro ao aplicativo por meio de um proxy reverso Nginx. O servidor Nginx oferecerá HTTPS usando um certificado gratuito fornecido pelo Let’s Encrypt.
Pré-requisitos
Este guia pressupõe que você tenha o seguinte:
- A Rocky Linux 9 server setup, as described in the initial server setup guide for Rocky Linux 9. You should have a non-root user with sudo privileges and an active firewall.
- A domain name pointed at your server’s public IP. This tutorial will use the domain name example.com throughout.
- O Nginx instalado, conforme abordado em Como Instalar o Nginx no Rocky Linux 9.
- O Nginx está configurado com SSL usando certificados Let’s Encrypt. Como Segurar o Nginx com Let’s Encrypt no Rocky Linux 9 irá orientá-lo pelo processo.
- O Node.js está instalado no seu servidor. Como Instalar o Node.js no Rocky Linux 9
Quando você completar os pré-requisitos, terá um servidor servindo a página padrão de espaço reservado do seu domínio em https://exemplo.com/
.
Passo 1 — Criando uma Aplicação Node.js
Vamos escrever uma aplicação Hello World que retorna “Hello World” para qualquer solicitação HTTP. Esta aplicação de exemplo ajudará você a iniciar com o Node.js. Você pode substituí-la por sua própria aplicação — apenas certifique-se de modificar sua aplicação para escutar nos endereços IP e portas apropriados.
O editor de texto padrão que vem com o Rocky Linux 9 é o vi
. O vi
é um editor de texto extremamente poderoso, mas pode ser um pouco obtuso para usuários inexperientes. Você pode querer instalar um editor mais amigável ao usuário, como o nano
, para facilitar a edição de arquivos de configuração no seu servidor Rocky Linux 9.
- sudo dnf install nano
Agora, usando o nano
ou o seu editor de texto favorito, crie uma aplicação de exemplo chamada hello.js
:
- nano hello.js
Insira o seguinte código no arquivo:
const http = require('http');
const hostname = 'localhost';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Salve o arquivo e saia do editor. Se estiver usando o nano
, pressione Ctrl+X
, depois, quando solicitado, Y
e, em seguida, Enter.
Esta aplicação Node.js escuta no endereço especificado (localhost
) e porta (3000
), e retorna “Hello World!” com um código de sucesso HTTP 200
. Como estamos ouvindo no localhost
, clientes remotos não conseguirão se conectar à nossa aplicação.
Para testar sua aplicação, digite:
- node hello.js
Você receberá a seguinte saída:
OutputServer running at http://localhost:3000/
Nota: Executar uma aplicação Node.js desta maneira bloqueará comandos adicionais até que a aplicação seja encerrada pressionando CTRL+C
.
Para testar a aplicação, abra outra sessão de terminal no seu servidor e conecte-se ao localhost
com o curl
:
- curl http://localhost:3000
Se você receber a seguinte saída, a aplicação está funcionando corretamente e ouvindo no endereço e porta corretos:
OutputHello World!
Se você não obter a saída esperada, certifique-se de que sua aplicação Node.js está em execução e configurada para ouvir no endereço e porta corretos.
Assim que tiver certeza de que está funcionando, encerre a aplicação (se ainda não o fez) pressionando CTRL+C
.
Passo 2 — Instalando o PM2
Em seguida, vamos instalar o PM2, um gerenciador de processos para aplicações Node.js. O PM2 torna possível a demonização de aplicações para que elas sejam executadas em segundo plano como um serviço.
Use o npm
para instalar a última versão do PM2 no seu servidor:
- sudo npm install pm2@latest -g
A opção -g
diz ao npm
para instalar o módulo globalmente, para que ele esteja disponível em todo o sistema.
Vamos primeiro usar o comando pm2 start
para executar sua aplicação, hello.js
, em segundo plano:
- pm2 start hello.js
Isso também adiciona sua aplicação à lista de processos do PM2, que é exibida toda vez que você inicia uma aplicação:
Output...
[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Como indicado acima, o PM2 atribui automaticamente um Nome do Aplicativo
(com base no nome do arquivo, sem a extensão .js
) e um id
do PM2. O PM2 também mantém outras informações, como o PID
do processo, seu status atual e uso de memória.
As aplicações que estão em execução sob o PM2 serão reiniciadas automaticamente se a aplicação travar ou for encerrada, mas podemos dar um passo adicional para fazer com que a aplicação seja iniciada na inicialização do sistema usando o subcomando startup
. Este subcomando gera e configura um script de inicialização para iniciar o PM2 e seus processos gerenciados na inicialização do servidor:
- pm2 startup systemd
Output…
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Copie e execute o comando fornecido (isso é para evitar problemas de permissões ao executar ferramentas Node.js como sudo
):
- sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Output…
[ 'systemctl enable pm2-sammy' ]
[PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service
[PM2] Making script booting at startup...
[PM2] [-] Executing: systemctl enable pm2-sammy...
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service.
[PM2] [v] Command successfully executed.
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save
[PM2] Remove init script via:
$ pm2 unstartup systemd
Agora, você precisará fazer uma edição no serviço do sistema que acabou de ser gerado para torná-lo compatível com o sistema de segurança SELinux do Rocky Linux. Usando o nano
ou seu editor de texto favorito, abra /etc/systemd/system/pm2-sammy.service
:
- sudo nano /etc/systemd/system/pm2-sammy.service
No bloco [Service]
do arquivo de configuração, substitua o conteúdo da configuração PIDFile
por /run/pm2.pid
conforme destacado abaixo, e adicione a outra linha Environment
destacada:
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target
[Service]
Type=forking
User=sammy
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/home/sammy/.local/bin:/home/sammy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/sammy/.pm2
PIDFile=/run/pm2.pid
Restart=on-failure
Environment=PM2_PID_FILE_PATH=/run/pm2.pid
ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill
[Install]
Salve e feche o arquivo. Agora você criou uma unidade systemd que executa o pm2
para o seu usuário durante o boot. Esta instância do pm2
, por sua vez, executa hello.js
.
Inicie o serviço com systemctl
:
- sudo systemctl start pm2-sammy
Verifique o status da unidade systemd:
- systemctl status pm2-sammy
Para uma visão geral detalhada do systemd, por favor, revise Systemd Essentials: Trabalhando com Serviços, Unidades e o Diário.
Além dos que cobrimos, o PM2 fornece muitos subcomandos que permitem gerenciar ou consultar informações sobre seus aplicativos.
Para parar um aplicativo com este comando (especifique o Nome do Aplicativo
ou id
do PM2):
- pm2 stop app_name_or_id
Para reiniciar um aplicativo:
- pm2 restart app_name_or_id
Lista os aplicativos atualmente gerenciados pelo PM2:
- pm2 list
Obtenha informações sobre um aplicativo específico usando seu Nome do Aplicativo
:
- pm2 info app_name
O monitor de processo PM2 pode ser acessado com o subcomando monit
. Isso exibe o status da aplicação, CPU e uso de memória:
- pm2 monit
Observe que executar pm2
sem argumentos também exibirá uma página de ajuda com exemplos de uso.
Agora que sua aplicação Node.js está em execução e sendo gerenciada pelo PM2, vamos configurar o proxy reverso.
Passo 3 — Configurando o Nginx como Servidor de Proxy Reverso
Sua aplicação está em execução e ouvindo em localhost
, mas você precisa configurar uma forma para que seus usuários a acessem. Vamos configurar o servidor web Nginx como um proxy reverso para esse fim.
No tutorial prévio, você configurou sua configuração do Nginx no arquivo /etc/nginx/conf.d/seu_domínio.conf
. Abra este arquivo para edição:
- sudo nano /etc/nginx/conf.d/your_domain.conf
Dentro do bloco server
, você deve ter um bloco location /
existente. Substitua o conteúdo desse bloco pela seguinte configuração. Se sua aplicação estiver configurada para ouvir em uma porta diferente, atualize a parte destacada para o número de porta correto:
server {
...
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
...
}
Esta configuração faz com que o servidor responda às solicitações em sua raiz. Supondo que nosso servidor esteja disponível em seu_domínio
, acessar https://seu_domínio/
através de um navegador da web enviará a solicitação para hello.js
, ouvindo na porta 3000
em localhost
.
Você pode adicionar blocos location
adicionais ao mesmo bloco de servidor para fornecer acesso a outras aplicações no mesmo servidor. Por exemplo, se você estiver executando outra aplicação Node.js na porta 3001
, poderia adicionar este bloco de localização para permitir o acesso a ela via https://seu_domínio/app2
:
server {
...
location /app2 {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
...
}
Depois de adicionar os blocos de localização para suas aplicações, salve o arquivo e saia do editor.
Certifique-se de não introduzir erros de sintaxe digitando:
- sudo nginx -t
Reinicie o Nginx:
- sudo systemctl restart nginx
Supondo que sua aplicação Node.js esteja em execução e suas configurações de aplicação e Nginx estejam corretas, agora você deverá conseguir acessar sua aplicação através do proxy reverso do Nginx. Experimente acessando a URL do seu servidor (seu endereço IP público ou nome de domínio).
Conclusão
Parabéns! Agora você tem sua aplicação Node.js em execução atrás de um proxy reverso do Nginx em um servidor Rocky Linux 9. Esta configuração de proxy reverso é flexível o suficiente para fornecer acesso dos usuários a outras aplicações ou conteúdo web estático que você deseja compartilhar.
A seguir, você pode querer dar uma olhada em Como construir uma aplicação Node.js com Docker.