Installazione

Questa guida illustra come installare interamente N.E.S.T. su un server Linux.

Prerequisiti

Per installare ed eseguire N.E.S.T., è necessario:

Creare un nuovo utente

Per motivi di sicurezza, si suggerisce di creare un nuovo utente con il quale eseguire il progetto:

Nota

È necessario essere amministratori di sistema per eseguire i seguenti comandi. Si veda il manuale di useradd per più dettagli.

root:~# mkdir --parents /srv/nest
root:~# useradd --home-dir /srv/nest --shell /bin/bash nest
root:~# chown --recursive nest: /srv/nest

Scaricare il codice sorgente

Per installare N.E.S.T., è necessario avere il codice sorgente disponibile sul server.

Si consiglia di scaricarlo tramite Git:

nest:~$ git clone https://gitlab.steffo.eu/nest/g2-progetto.git

Questo creerà una nuova cartella g2-progetto nella directory in cui è stato eseguito il comando.

Per proseguire, sarà necessario entrarvi:

nest:~$ cd g2-progetto

Creare il database

N.E.S.T. necessita di un database PostgreSQL in cui salvare i dati.

Per motivi di sicurezza, si suggerisce di creare un ruolo isolato dal resto del DBMS apposta per N.E.S.T.:

postgres:~$ createuser nest

Per creare il database PostgreSQL, si esegua:

postgres:~$ createdb --owner=nest nest

Creare un file di configurazione per il backend

Il backend usa un file di configurazione per impostare alcune variabili.

Si crei un nuovo file nella working directory del progetto denominato config.py:

nest:~/g2-progetto$ vim config.py

Il file dovrà avere i seguenti contenuti:

# Una stringa rappresentante il database da utilizzare
# Per maggiori informazioni sulla sintassi, si veda https://docs.sqlalchemy.org/en/14/core/engines.html
SQLALCHEMY_DATABASE_URI = "postgresql://nest@/nest"

# Una stringa casuale utilizzata per generare i JSON Web Token (JWT)
# Va mantenuta segreta e costante per tutta l'operazione del backend!
# Si suggerisce di premere tasti casuali sulla tastiera finchè la riga non è piena.
SECRET_KEY = "dsjiofgvinmodfiojvbnio3erfnoiweraqugu43ghjwrevniuwerng43iugnreuwignhritmj43i43nb8i42ug0wevkwovmwigtjj"

Installare le dipendenze Python

Le dipendenze Python sono gestite da Poetry, e possono essere installate con:

nest:~/g2-progetto$ poetry install

Poetry creerà automaticamente un venv e vi installerà all'interno tutti i pacchetti necessari all'esecuzione del backend e del crawler di N.E.S.T. .

Si suggerisce di ricordare il nome del venv creato da Poetry, in quanto sarà necessario per Creare un servizio SystemD per il backend:

Creating virtualenv nest-7C2fm2VD-py3.9 in /srv/nest/.cache/pypoetry/virtualenvs

Installare le dipendenze NodeJS

Le dipendenze NodeJS sono gestite da npm, e possono essere installate con:

nest:~/g2-progetto$ npm install

npm creerà automaticamente una cartella node_modules e vi installerà all'interno tutte le librerie necessarie all'esecuzione del frontend di N.E.S.T. .

Creare un servizio SystemD per il backend

Per fare in modo che il backend rimanga attivo in background, anche dopo un riavvio, si suggerisce di installarlo come servizio di sistema di SystemD:

root:~# systemctl edit --force --full nest-backend

Inserire all'interno del file le seguenti direttive:

[Unit]
Description=N.E.S.T. Backend
Wants=network-online.target postgresql.service
After=network-online.target nss-lookup.target postgresql.service

[Service]
Type=exec
User=nest
Group=nest
WorkingDirectory=/srv/nest/g2-progetto

# Si sostituisca a questo il percorso del virtualenv creato in precedenza da Poetry
#         ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
ExecStart=/srv/nest/.cache/pypoetry/virtualenvs/nest-7C2fm2VD-py3.9/bin/python -m gunicorn -b 127.0.0.1:30040 --env="FLASK_CONFIG=../config.py" nest_backend.app:rp_app

[Install]
WantedBy=multi-user.target

Ora, si verifichi che il servizio si avvii correttamente eseguendolo manualmente con:

root:~# systemctl start nest-backend

In caso di successo, l'API dovrebbe essere esposto sulla porta 30040 dell'indirizzo di loopback 127.0.0.1:

root:~# curl 127.0.0.1:30040/doa
If you see this, the server is fine.

Si abiliti il servizio, in modo che venga automaticamente avviato al riavvio del sistema:

root:~# systemctl enable nest-backend

Compilare il frontend

Perchè sia possibile servire il frontend agli utenti, è necessario prima crearne una versione compilata ottimizzata.

È possibile farlo con il comando:

nest:~/g2-progetto$ npm run build

Verrà creata una cartella build con all'interno la versione compilata.

Creare un servizio SystemD per il frontend

Per rendere disponibile alla rete la copia locale del frontend, si suggerisce di avviare lo script npm serve integrato con N.E.S.T. come un servizio di sistema di SystemD:

root:~# systemctl edit --force --full nest-frontend

Inserire all'interno del file le seguenti direttive:

[Unit]
Description=N.E.S.T. Frontend
Wants=network-online.target nest-backend.service
After=network-online.target nss-lookup.target nest-backend.service

[Service]
Type=exec
Environment=NODE_ENV=production
User=nest
Group=nest
WorkingDirectory=/srv/nest/g2-progetto
ExecStart=/usr/bin/npm run serve

[Install]
WantedBy=multi-user.target

Avvertimento

Questo file non è stato testato, in quanto sul server demo è in uso una versione più complessa che usa nvm per gestire più versioni di NodeJS sullo stesso sistema.

La versione in uso sul server demo è:

[Unit]
Description=N.E.S.T. Frontend
Wants=network-online.target nest-backend.service
After=network-online.target nss-lookup.target nest-backend.service

[Service]
Type=exec
Environment=NODE_ENV=production
Environment=NODE_VERSION=16
User=nest
Group=nest
WorkingDirectory=/srv/nest/g2-progetto
ExecStart=/srv/nest/.nvm/nvm-exec npm run serve

[Install]
WantedBy=multi-user.target

Ora, si verifichi che il servizio si avvii correttamente eseguendolo manualmente con:

root:~# systemctl start nest-frontend

In caso di successo, il frontend dovrebbe essere esposto sulla porta 30041 dell'indirizzo di loopback 127.0.0.1:

root:~# curl 127.0.0.1:30041
[...]

Si abiliti il servizio, in modo che venga automaticamente avviato al riavvio del sistema:

root:~# systemctl enable nest-frontend

Creare un servizio SystemD per il crawler

Perchè i repository vengano popolati di Tweet, è necessario configurare il crawler come servizio di SystemD:

root:~# systemctl edit --force --full nest-crawler

All'interno del file, inserire le seguenti direttive:

[Unit]
Description=N.E.S.T. Crawler
Wants=network-online.target nest-backend.service
After=network-online.target nss-lookup.target nest-backend.service

[Service]
Type=exec
Environment=FLASK_CONFIG=../config.py
User=nest
Group=nest
WorkingDirectory=/srv/nest/g2-progetto
# Si sostituisca a questo il percorso del virtualenv creato in precedenza da Poetry
#         ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
ExecStart=/srv/nest/.cache/pypoetry/virtualenvs/nest-7C2fm2VD-py3.9/bin/python -m nest_crawler

[Install]
WantedBy=multi-user.target

Configurare il crawler

Nota

Per utilizzare gli API di Twitter, è necessario essere approvati dal supporto tecnico di Twitter.

È dunque necessario fare richiesta, e sarà possibile procedere con l'installazione solo una volta ricevute le credenziali per l'utilizzo.

Per impostare le variabili di ambiente richieste dal crawler, si suggerisce di creare un file di override di SystemD:

root:~# systemctl edit nest-crawler

All'interno del file, inserire le seguenti direttive:

[Service]

# Sostituire a questi caratteri la Consumer Key ricevuta da Twitter
#               ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Environment=C_K=0000000000000000000000000


# Sostituire a questi caratteri il Consumer Secret ricevuto da Twitter
#               ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Environment=C_S=00000000000000000000000000000000000000000000000000

# Sostituire a questi caratteri l'Access Token ricevuto da Twitter
#               ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Environment=A_T=00000000000000000000000000000000000000000000000000

# Sostituire a questi caratteri l'Access Token Secret ricevuto da Twitter
#                 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Environment=A_T_S=000000000000000000000000000000000000000000000

# Sostituire con l'indirizzo del proprio SMTP mail server
#                     ↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Environment=SMTP_HOST=mail.gandi.net

# Sostituire con le proprie credenziali dell'SMTP mail server
#                         ↓↓↓↓↓↓↓↓↓↓↓↓
Environment=SMTP_USERNAME=bot@ryg.one
#                         ↓↓↓↓↓↓↓↓
Environment=SMTP_PASSWORD=password

# Sostituire con l'email da cui si desidera che vengano inviate le allerte
#                           ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
Environment=SMTP_FROM_EMAIL=nest-bot@ryg.one

Ora, si verifichi che il servizio si avvii correttamente eseguendolo manualmente con:

root:~# systemctl start nest-crawler

Nel log di sistema non dovrebbe comparire nessun errore:

root:~# journalctl nest-crawler

Creare un timer SystemD per il crawler

Per fare in modo che il crawler venga eseguito periodicamente, si suggerisce di configurare un timer SystemD:

root:~# systemctl edit --force --full nest-crawler.timer

Si inseriscano all'interno del file le seguenti direttive:

[Unit]
Description=Run nest-crawler every 60 minutes

[Timer]
OnBootSec=60min
OnUnitActiveSec=60min
Unit=nest-crawler.service

[Install]
WantedBy=timers.target

Ora, si verifichi che il timer si avvii correttamente eseguendolo manualmente con:

root:~# systemctl start nest-crawler.timer

Nello stato del timer non dovrebbe comparire nessun errore:

root:~# systemctl status nest-crawler.timer

Si abiliti il timer, in modo che venga automaticamente avviato al riavvio del sistema:

root:~# systemctl enable nest-crawler.timer

Configurare Apache come reverse proxy

Per rendere l'API e il frontend disponibili al pubblico, si suggerisce di configurare Apache HTTP Server come reverse proxy.

La configurazione di Apache varia molto da distribuzione a distribuzione Linux, e talvolta anche da server a server; pertanto, si fornisce solamente un file VirtualHost di esempio da adattare al proprio setup:

<VirtualHost *:80>
    ServerName "api.nest.steffo.eu"
    ServerName "prod.nest.steffo.eu"

    RewriteEngine On
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName "api.nest.steffo.eu"

    SSLEngine on
    SSLCertificateFile      "/root/.acme.sh/*.nest.steffo.eu/fullchain.cer"
    SSLCertificateKeyFile   "/root/.acme.sh/*.nest.steffo.eu/*.nest.steffo.eu.key"

    ProxyPass           "/" "http://127.0.0.1:30040/"
    ProxyPassReverse    "/" "http://127.0.0.1:30040/"
    RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}

    Protocols h2 http/1.1
    Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>

<VirtualHost *:443>
    ServerName "prod.nest.steffo.eu"

    SSLEngine on
    SSLCertificateFile      "/root/.acme.sh/*.nest.steffo.eu/fullchain.cer"
    SSLCertificateKeyFile   "/root/.acme.sh/*.nest.steffo.eu/*.nest.steffo.eu.key"

    ProxyPass           "/" "http://127.0.0.1:30041/"
    ProxyPassReverse    "/" "http://127.0.0.1:30041/"
    RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}

    Protocols h2 http/1.1
    Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>