Deploy di un'applicazione nodejs con MongoDB e certificato SSL

Deploy di un'applicazione nodejs con MongoDB e certificato SSL

In questo articolo vedremo il procedimento passo passo per fare il deploy di un'app Nodejs su un server, renderla sicura con un certificato SSL  gratuito e infine punteremo un dominio alla nostra app.

In questo esempio utilizzerò un server Digital Ocean, ma sono presenti molti servizi simili come Vultr o Linode che sono ugualmente validi.

Prerequisiti

  • Un server a cui poter accedere via SSH
  • Il progetto caricato su github 
  • Un dominio a cui poter modificare i record DNS
  • Una conoscenza base dei comandi linux

Creazione nuovo utente

Dato che nel server è presente un utente root - che ha potere di vita e di morte all'interno del server stesso - è buona regola disabilitare l'accesso a questo utente; dobbiamo quindi precedere alla creazione di un nuovo utente che ci permetta di eseguire le operazioni di cui abbiamo necessità.

Il primo passo è quello di collegartci via SSH al server:

ssh root@indirizzo_server

Una volta all'interno del server possiamo procedere alla creazione del nuovo utente con il comando:

# Inserire un nome a scelta per lo user
adduser fabio

Verrà richiesta una password, assicuriamoci di ricordala in quanto ci servirà in seguito e alcuni dati opzionali. A questo punto possiamo assicurarci che l'utente sia stato effettivamente creato utilizzando il comando id, da cui otterremo un risultato simile a questo:

 root@Ubuntu22:~# id fabio 
 uid=1001(fabio) gid=1001(fabio) groups=1001(fabio)

Ora possiamo procedere ad inserire l'utente appena creato nel gruppo sudo

usermod -aG sudo fabio

Il passo successivo è l'aggiunta della chiave SSH per il nuovo utente che ci permetterà di eseguire l'accesso senza l'utilizzo della password

# Diventa il nuovo utente 
 su - fabio
 
 # Crea una nuova directory
 mkdir ~/.ssh 
 
# Imposta i permessi di accesso alla cartella
 chmod 700 ~/.ssh
 
 # Crea un file per le chiavi SSH e apre l’editor nano
 nano ~/.ssh/authorized_keys 

All'interno del file andiamo ad inserire la nostra chiave pubblica e salviamo premendo control+x seguito da y e dal tasto invio.

# Imposta i permessi di accesso al solo utente
chmod 600 ~/.ssh/authorized_keys 

# Torna ad essere utente root 
exit

Dal passaggio precedente dovremmo essere loggati nel server come utente root, testiamo che il nuovo utente possa accedere al server:

# Usciamo dal server
exit 

# Logghiamoci come nuovo utente 
ssh fabio@indirizzo_server

Nota: Se la chiave SSH del nostro PC non si trova nel percorso di default (~/.ssh ) o se ha un nome diverso da id_rsa, dobbiamo specificare sia il percorso che il nome della chiave privata affinchè il collegamento funzioni

ssh -i ~/percorso/nome_file_chiave_privata fabio@indirizzo_server

Possiamo ora procedere a disabilitare il login come root e l'accesso con la password:

sudo nano /etc/ssh/sshd_config

All'interno di questo file cerchiamo le voci PermitRootLogin, PubkeyAuthentication e PasswordAuthentication e assicuriamoci di decommentarle nel caso avessero davanti il simbolo # e impostiamole come segue:

PermitRootLogin no 
PubkeyAuthentication yes 
PasswordAuthentication no

Salviamo il file come fatto precedentemente con contro+x, y ed invio e riavviamo il servizio SSH

# Ricarica la configurazione appena modificata 
sudo systemctl reload sshd

Procediamo a questo punto a verificare che tutto funzioni; apriamo una nuova finestra del terminale e entriamo con l'utente appena creato

Non chiudere la finestra del terminale precedente o effettuare il logout. Se qualcosa non dovesse funzionare a dovere non potremmo più accedere al server. 

Se ci loghiamo con il nuovo utente tutto funziona come previsto, ma se proviamo ad accedere come utente root riceviamo un messaggio di errore.

Impostiamo un firewall di base

Passiamo a configurare un semplice firewall che ci consenta di permettere il traffico sulle porte HTTP (80) , HTTPS (443), permetta la connessione SSH e blocchi il resto  del traffico, lanciando questa serie di comandi dalla shell:

# Abilita le connessioni OpenSSH 
sudo ufw allow OpenSSH 

# Abilita il traffico HTTP 
sudo ufw allow http 

# Abilita il traffico HTTP 
sudo ufw allow https

# Attiva il firewall 
sudo ufw enable

Una volta abilitato il firewall riceviamo un avviso che questo potrebbe impedirci la connessione, possiamo non preoccuparcene avendo abilitato le connessioni SSH. Possiamo ora controllare lo stato del firewall con il comando

sudo ufw status

Installazione di htop e nginx

Proseguiamo con un primo passaggio opzionale, ovvero l'installazione di htop; htop è un process viewer che una volta installato ci permette di monitorare i processi fornendoci maggiori informazioni e opzioni come la possibilità di  filtrarli o di ordinarli.

sudo apt install htop 

htop
Schermata di htop

Passiamo ora all'installazione di nginx lanciando i seguenti comandi:

# Aggiorna i repository dei pacchetti 
sudo apt update 

#Installa nginx 
sudo apt install nginx 

#Verifica che nginx sia attivo 
service nginx status

Possiamo verificare che l'installazione sia andata a buon fine andando con il browser all'indirizzo IP del nostro server dove vedremo questa pagina:

Pagina di default di nginx

Installare MongoDB e Nodejs

Continuiamo andando ad installare il DBMS, nel nostro caso si tratta di MongoDB; l'installazione è molto semplice e avviene lanciando un solo comando:

sudo apt install mongodb

Una volta terminata l'installazione possiamo verificare che il servizio sia attivo

service mongodb status

Un passaggio importante è quello di verificare, lanciando il comando mongo, che il server stia girando sulla porta 27017 con indirizzo 127.0.0.1 e assicurarci che non sia accessibile da browser all'indirizzo IP_server:27017.

A questo punto possiamo passare all'installazione di Nodejs

#Installa npm e node 
sudo apt install npm 

#Installa il gestore di versione di node 
sudo npm i -g n 

#Installa la versione 18.x di node 
sudo n 18

Clonare il progetto da git

Per prima cosa assicuriamoci che git sia installato

git --version

Nel caso non lo fosse possiamo installarlo con il comando sudo apt install git.

Per clonare il progetto abbiamo bisogno di generare sul server le chiavi SSH; per fare questo loghiamoci diventiamo utente root e procediamo come segue:

#Diventa utente root 
fabio@prova:~$ su 

#Genera le chiavi SSH 
root@prova:/home/fabio# ssh-keygen 

#Stampa a video il contenuto del file 
root@prova:/home/fabio# cat ~/.ssh/id_rsa.pub

Copiamo la chiave e aggiungiamola alle chiavi SSH di github.

Ora dobbiamo spostarci nella cartella /var/www dive andremo ad inserire il nostro progetto

root@prova:~/.ssh# cd /var/www 

#Clona il progetto 
root@prova:/var/www# git clone git@github.com:nome_utente/nome_progetto.git 

#Entra nella cartella del progetto 
root@prova:/var/www# cd nome_progetto/ 

#Installa le dipendenze 
root@prova:/var/www/nome_progetto# npm i 

#Torna utente normale 
root@prova:/var/www/nome_progetto# exit

A questo punto possiamo testare che la nostra app funzioni; spostiamoci nella cartella del progetto e avviamo l'applicazione

cd /var/www/nome_progetto/ 

node app.js

Nel nostro esempio l'applicazione è in ascolto sulla porta 3000, apriamo quindi una nuova finestra del terminale, loghiamoci e lanciamo una request curl all'app

fabio@prova:~$ curl http://127.0.0.1:3000/ 
<!DOCTYPE html> 
<html lang="en"> git
<head> 
        <meta charset="UTF-8"> 
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

Una volta effettuata la verifica possiamo uscire da questa sessione del terminale e fermare l'applicazione con contrl+c.

Installare PM2

Un problema in cui si può incorrere è quello nel caso in cui il server venisse riavviato, in questo caso dovremmo entrare nel server e riavviare manualmente la nostra applicazione; PM2 è un pacchetto che ci solleva da questa incombenza riavviando automaticamente l'app alla ripartenza del server.

sudo npm install -g pm2

Dalla cartella del progetto lanciamo il comando

fabio@prova:/var/www/nome_progetto$ pm2 start app.js

Per assicuraci che PM2 riavvi la nostra app il comando è

pm2 startup

che ci restituisce questo messaggio:

[PM2] Init System found: systemd 
[PM2] To setup the Startup Script, copy/paste the following command: 
sudo env PATH=$PATH:/usr/local/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u fabio --hp /home/fabio

Lanciamo il comando richiesto e salviamo

sudo env PATH=$PATH:/usr/local/bin /usr/ local/lib/node_modules/pm2/bin/pm2 startup systemd -u fabio --hp /home/fabio 

pm2 save

Ora riavviando il server e lanciando nuovamente una richiesta curl vedremo che l'applicazione è stata riavviata in automatico.

Configurare il dominio per puntare al server

Occupiamoci ora di puntare i record dns del dominio al server, per questo esempio userò un dominio acquistato su namecheap ma la stessa operazione può essere effettuata con praticamente ogni servizio che vi permetta di registrare un dominio.

Rechiamoci nella sezione  dei record dns e inseriamo questi due record:

Record A
Record cname

Possiamo verificare che tutto funzioni con il comando

dig +short dominio.ext

che deve restituirci l'indirizzo IP del server e

dig +short www.dominio.ext

che oltre all'indirizzo IP ci restituisce il nome dominio senza www

Adesso per rendere accessibile l'applicazione  andiamo a modificare un file di nginx

sudo nano /etc/nginx/sites-available/default

Qui andiamo ad aggiungere il seguente codice nella sezione location

server_name dominio.ext www.dominio.ext; 
location / { 
        proxy_pass http://127.0.0.1:3000; #Inserire la porta usata nell’app 
        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; 
}

Salviamo il file e controlliamo che non ci siano errori al suo interno

sudo nginx -t

Riavviamo infine il servizio nginx

sudo systemctl reload nginx

Ora possiamo visualizzare l'applicazione dal browser inserendo il nome dominio sia con www che senza.

Installare un certificato SSL con Let’s Encrypt

L'ultimo passaggio è quello di installare il certificato SSL, per questo utilizzeremo let's encrypt che è una Certification Authority che rilascia gratuitamente certificati della durata di 90 giorni.

Per prima cosa installiamo Certbot

#Installa snapd 
sudo snap install core 

#Controlla che snapd sia aggiornato 
sudo snap refresh core 

#Rimuove certbot-auto ed ogni pacchetto certbot 
sudo apt-get remove certbot

#Installa certbot con snap 
sudo snap install --classic certbot 

#Crea un link a certbot in usr/bin 
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Installiamo ora il certificato inserendo il nome dominio e un indirizzo email valido

sudo certbot --nginx --redirect -d example.com -d www.example.com -m admin@example.it --agree-tos

Abilitiamo infine il rinnovo automatico alla scadenza del certificato

#Verifica che il timer sia attivo 
systemctl list-timers | grep 'certbot\|ACTIVATES' 

#Verifica che il processo di rinnovo funzioni 
sudo certbot renew --dry-run

Ora la nostra app è pubblicata ed accessibile con il protocollo HTTPS.

Link utili

Se vuoi creare il tuo sito web contattami per un preventivo gratuito

© 2023 Fabio Angelici

P.I. 03929520124

Privacy policy Cookie policy Hostinger Referral Badge