Introduzione
Node.js è un ambiente di runtime JavaScript open-source per la creazione di applicazioni lato server e di rete. La piattaforma funziona su Linux, macOS, FreeBSD e Windows. Anche se è possibile eseguire le applicazioni Node.js dalla riga di comando, questo tutorial si concentrerà su come eseguirle come servizio. Ciò significa che si riavvieranno all’avvio o in caso di errore e sono sicure per l’uso in un ambiente di produzione.
In questo tutorial, configurerai un ambiente Node.js pronto per la produzione su un singolo server Rocky Linux 9. Questo server eseguirà un’applicazione Node.js gestita da PM2, e fornirà agli utenti un accesso sicuro all’applicazione tramite un proxy inverso Nginx. Il server Nginx offrirà HTTPS utilizzando un certificato gratuito fornito da Let’s Encrypt.
Prerequisiti
Questa guida presume che tu abbia quanto segue:
- 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.
- Nginx installato, come descritto in Come installare Nginx su Rocky Linux 9.
- Nginx configurato con SSL utilizzando certificati Let’s Encrypt. Come Sicurizzare Nginx con Let’s Encrypt su Rocky Linux 9 ti guiderà attraverso il processo.
- Node.js installato sul tuo server. Come Installare Node.js su Rocky Linux 9
Una volta completati i prerequisiti, avrai un server che serve la pagina segnaposto predefinita del tuo dominio su https://esempio.com/
.
Passo 1 — Creazione di un’applicazione Node.js
Scriviamo un’applicazione Hello World che restituisce “Hello World” a qualsiasi richiesta HTTP. Questa applicazione di esempio ti aiuterà a iniziare con Node.js. Puoi sostituirla con la tua applicazione, assicurandoti di modificare l’applicazione per ascoltare sugli indirizzi IP e le porte appropriate.
L’editor di testo predefinito in Rocky Linux 9 è vi
. vi
è un editor di testo estremamente potente ma può essere un po’ ostico per gli utenti meno esperti. Potresti voler installare un editor più user-friendly come nano
per facilitare la modifica dei file di configurazione sul tuo server Rocky Linux 9:
- sudo dnf install nano
Ora, utilizzando `nano` o il tuo editor di testo preferito, crea un’applicazione di esempio chiamata `hello.js`:
- nano hello.js
Inserisci il seguente codice nel file:
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}/`);
});
Salva il file ed esci dall’editor. Se stai usando `nano`, premi `Ctrl+X`, quindi quando richiesto, `Y` e poi Invio.
Questa applicazione Node.js ascolta sull’indirizzo specificato (`localhost`) e sulla porta (`3000`), e restituisce “Hello World!” con un codice di successo HTTP `200`. Poiché stiamo ascoltando su `localhost`, i client remoti non saranno in grado di connettersi alla nostra applicazione.
Per testare la tua applicazione, digita:
- node hello.js
Riceverai il seguente output:
OutputServer running at http://localhost:3000/
Nota: Eseguire un’applicazione Node.js in questo modo bloccherà ulteriori comandi fino a quando l’applicazione non sarà interrotta premendo `CTRL+C`.
Per testare l’applicazione, apri un’altra sessione terminale sul tuo server e connettiti a `localhost` con `curl`:
- curl http://localhost:3000
Se ottieni il seguente output, l’applicazione funziona correttamente e sta ascoltando sull’indirizzo e sulla porta corretti:
OutputHello World!
Se non ottieni l’output atteso, assicurati che la tua applicazione Node.js sia in esecuzione e configurata per ascoltare sull’indirizzo e sulla porta corretti.
Una volta sicuro che funzioni, interrompi l’applicazione (se non l’hai già fatto) premendo `CTRL+C`.
Fase 2 — Installazione di PM2
Successivamente procediamo con l’installazione di PM2, un gestore di processi per le applicazioni Node.js. PM2 consente di demonizzare le applicazioni in modo che vengano eseguite in background come un servizio.
Usa npm
per installare l’ultima versione di PM2 sul tuo server:
- sudo npm install pm2@latest -g
l’opzione -g
indica a npm
di installare il modulo globalmente, in modo che sia disponibile a livello di sistema.
Cominciamo usando il comando pm2 start
per eseguire la tua applicazione, hello.js
, in background:
- pm2 start hello.js
Questo aggiunge anche la tua applicazione all’elenco dei processi di PM2, che viene visualizzato ogni volta che avvii un’applicazione:
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 │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Come indicato sopra, PM2 assegna automaticamente un Nome App
(basato sul nome del file, senza l’estensione .js
) e un id
di PM2. PM2 mantiene anche altre informazioni, come il PID
del processo, il suo stato attuale e l’utilizzo della memoria.
Le applicazioni in esecuzione con PM2 verranno riavviate automaticamente se l’applicazione si blocca o viene interrotta, ma possiamo fare un ulteriore passo avanti per far sì che l’applicazione si avvii all’avvio del sistema usando il sottocomando startup
. Questo sottocomando genera e configura uno script di avvio per avviare PM2 e i suoi processi gestiti all’avvio del server:
- 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
Copia ed esegui il comando fornito (questo serve per evitare problemi di autorizzazioni con l’esecuzione degli strumenti Node.js come 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
Ora, sarà necessario apportare una modifica al servizio di sistema appena generato per renderlo compatibile con il sistema di sicurezza SELinux di Rocky Linux. Utilizzando nano
o il tuo editor di testo preferito, apri /etc/systemd/system/pm2-sammy.service
:
- sudo nano /etc/systemd/system/pm2-sammy.service
Nel blocco [Service]
del file di configurazione, sostituisci il contenuto dell’opzione PIDFile
con /run/pm2.pid
come evidenziato di seguito, e aggiungi l’altra riga evidenziata Environment
:
[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]
Salva e chiudi il file. Hai ora creato un’unità di sistema systemd che esegue pm2
per il tuo utente all’avvio. Questa istanza di pm2
, a sua volta, esegue hello.js
.
Avvia il servizio con systemctl
:
- sudo systemctl start pm2-sammy
Verifica lo stato dell’unità di sistema systemd:
- systemctl status pm2-sammy
Per una panoramica dettagliata di systemd, consulta Systemd Essentials: Working with Services, Units, and the Journal.
Oltre a quelli che abbiamo coperto, PM2 fornisce molti sottocomandi che ti consentono di gestire o visualizzare informazioni sulle tue applicazioni.
Interrompi l’esecuzione di un’applicazione con questo comando (specificare il nome dell’applicazione PM2 o l’id
di PM2):
- pm2 stop app_name_or_id
Riavvia un’applicazione:
- pm2 restart app_name_or_id
Elencare le applicazioni attualmente gestite da PM2:
- pm2 list
Ottenere informazioni su un’applicazione specifica utilizzando il suo nome dell'applicazione
:
- pm2 info app_name
Il monitor dei processi PM2 può essere visualizzato con il sottocomando monit
. Questo mostra lo stato dell’applicazione, l’utilizzo della CPU e della memoria:
- pm2 monit
Nota che eseguire pm2
senza argomenti mostrerà anche una pagina di aiuto con esempi di utilizzo.
Ora che la tua applicazione Node.js è in esecuzione e gestita da PM2, impostiamo il proxy inverso.
Passaggio 3 — Configurazione di Nginx come server proxy inverso
La tua applicazione è in esecuzione e in ascolto su localhost
, ma è necessario configurare un modo per consentire ai tuoi utenti di accedervi. Configureremo il server web Nginx come proxy inverso a questo scopo.
Nel tutorial preliminare, hai configurato la tua configurazione Nginx nel file /etc/nginx/conf.d/your_domain.conf
. Apri questo file per la modifica:
- sudo nano /etc/nginx/conf.d/your_domain.conf
All’interno del blocco server
, dovresti avere un blocco location /
esistente. Sostituisci il contenuto di quel blocco con la seguente configurazione. Se la tua applicazione è impostata per ascoltare su una porta diversa, aggiorna la parte evidenziata con il numero di porta corretto:
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;
}
...
}
Questo configura il server per rispondere alle richieste alla sua radice. Supponendo che il nostro server sia disponibile su your_domain
, l’accesso a https://your_domain/
tramite un browser invierebbe la richiesta a hello.js
, in ascolto sulla porta 3000
su localhost
.
Puoi aggiungere ulteriori blocchi location
allo stesso blocco del server per fornire accesso ad altre applicazioni sullo stesso server. Ad esempio, se stessi eseguendo un’altra applicazione Node.js sulla porta 3001
, potresti aggiungere questo blocco di posizione per consentire l’accesso tramite https://your_domain/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;
}
...
}
Una volta che hai finito di aggiungere i blocchi di posizione per le tue applicazioni, salva il file ed esci dall’editor.
Assicurati di non aver introdotto errori di sintassi digitando:
- sudo nginx -t
Riavvia Nginx:
- sudo systemctl restart nginx
Presumendo che la tua applicazione Node.js sia in esecuzione e che le tue configurazioni dell’applicazione e di Nginx siano corrette, ora dovresti poter accedere alla tua applicazione tramite il proxy inverso di Nginx. Provalo accedendo all’URL del tuo server (il suo indirizzo IP pubblico o il nome di dominio).
Conclusione
Congratulazioni! Ora hai la tua applicazione Node.js in esecuzione dietro un proxy inverso Nginx su un server Rocky Linux 9. Questa configurazione del proxy inverso è sufficientemente flessibile da fornire ai tuoi utenti l’accesso ad altre applicazioni o contenuti web statici che desideri condividere.
Prossimo, potresti voler dare un’occhiata a Come creare un’applicazione Node.js con Docker.