Introduzione

In questo tutorial vedremo come creare un applicazione scritta in Python utilizzando il microframework Flask.
Come utilizzare il server Gunicorn e avviare l'applicazione configurando Nginx come reverse proxy su Ubuntu 18.04 LTS.

Prerequisiti

Prima di iniziare con questa guida, dovresti avere un utente non root con i privilegi sudo impostati sul tuo server. Segui questa guida: Configurazione Iniziale su Ubuntu 18.04 LTS.

Utilizzeremo Nginx come reverse proxy, quindi se non avete Nginx installato seguire questa guida: Come installare LEMP su Ubuntu 18.04 LTS. È sufficiente seguire il primo step.

Inoltre è necessario un nome dominio attivo che punti al proprio server.

Installare le Dipendenze necessarie

Aggiornare l'elenco dei pacchetti di Ubuntu, da terminale:
sudo apt update

Installare i pacchetti indispensabili:
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

Creare un Ambiente Virtuale

Configurare un ambiente virtuale per isolare la nostra applicazione Flask dagli altri file Python sul sistema.

Installare python3-venv:
sudo apt install python3-venv

Creare una cartella per la vostra applicazione:
mkdir ~/myapp

Entrare nella cartella:
cd ~/myapp

Creare un ambiente virtuale Python per il nostro progetto:
python3.6 -m venv myappenv

Verrà installata una copia locale di Python e pip nel nostro progetto.

Attivare il nostro ambiente virtuale:
source myappenv/bin/activate

Il tuo prompt dovrebbe cambiare per indicare che stai ora operando all'interno di un ambiente virtuale Python.
Esempio:
(myappenv) [email protected]:~/myapp$.

Creare un App Flask

Installare il pacchetto wheel:
pip install wheel

Quando l'ambiente virtuale è attivato utilizzare pip invece di pip3, anche se si sta utilizzando Python 3.

Installare Flask e Gunicorn:
pip install gunicorn flask

Creare un file python per la nostra applicazione:
nano ~/myapp/myapp.py

Incollare le seguenti righe di codice:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:red'>Hello World!</h1>"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

Di default verrà usata la porta 5000 se riscontrate problemi, o avete questa porta già utilizzata da un'altra applicazione, potete cambiarla modificando l'ultima riga di codice, per esempio:

...
    app.run(host='0.0.0.0',port='5040')
...

Salvare e chiudere il file

Se avete il firewall (ufw) di Ubuntu attivo, sarà necessario aprire le porte necessarie:
sudo ufw allow 5000

Oppure:
sudo ufw allow 5040

Testare l'applicazione:
python myapp.py

Dovresti ricevere un messaggio di output simile al seguente:

* Serving Flask app "myapp" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Aprire il browser e collegarsi al proprio indirizzo, specificando il numero della porta:

http://tuo_indirizzo_ip:5000

Dovresti visualizzare il messaggio: Hello World!

Da terminale, premere CTRL-C per chiudere l'applicazione.

Creare il file WSGI

Il file WSGI fungerà da punto di ingresso per la nostra applicazione. Questo dirà al nostro server Gunicorn come interagire con l'applicazione.

Creare il file wsgi.py:
nano ~/myapp/wsgi.py

In questo file, importiamo ed eseguiamo l'istanza Flask dalla nostra applicazione.

Incollare le seguenti righe di codice:

from myapp import app

if __name__ == "__main__":
    app.run()

Salvare e chiudere il file.

Configurare Gunicorn

Innanzitutto testare il punto di ingresso stabilito con il file wsgi.py.

Assicurarsi di trovarsi nella directory corretta:
cd ~/myapp

Controllare che Gunicorn possa service correttamente la nostra applicazione con il seguente comando:
gunicorn --bind 0.0.0.0:5000 wsgi:app

Dovreste ricevere un messaggio di output simile al seguente:

[2018-08-04 15:36:40 +0200] [19809] [INFO] Starting gunicorn 19.9.0
[2018-08-04 15:36:40 +0200] [19809] [INFO] Listening at: http://0.0.0.0:5000 (19809)
[2018-08-04 15:36:40 +0200] [19809] [INFO] Using worker: sync
[2018-08-04 15:36:40 +0200] [19812] [INFO] Booting worker with pid: 19812

Aprire il browser e collegarsi al proprio indirizzo, specificando il numero della porta:

http://tuo_indirizzo_ip:5000

Dovresti visualizzare il messaggio: Hello World!

Da terminale, premere CTRL-C per chiudere l'applicazione.

Disattivare l'ambiente virtuale:
deactivate

Qualsiasi comando Python ora utilizzerà nuovamente l'ambiente Python del sistema.

Creare il file systemd service. La creazione di questo file consentirà al sistema init di Ubuntu di avviare automaticamente Gunicorn e servire l'applicazione Flask all'avvio del server.

Creare un file unit che termina con .service all'interno della directory /etc/systemd/system:
sudo nano /etc/systemd/system/myapp.service

Incollare le seguenti righe di codice, facendo attenzione a modificare l'user e i nomi delle cartelle che avete scelto:

[Unit]
Description=Gunicorn instance to serve myapp
After=network.target

[Service]
User=noviello
Group=www-data
WorkingDirectory=/home/noviello/myapp
Environment="PATH=/home/noviello/myapp/myappenv/bin"
ExecStart=/home/noviello/myapp/myappenv/bin/gunicorn --workers 3 --bind unix:/tmp/myapp.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

Salvare e chiudere il file.

Avviare il progetto:
sudo systemctl start myapp

Abilitare il progetto all'avvio:
sudo systemctl enable myapp

Controllare lo stato dell'applicazione:
sudo systemctl status myapp

Dovreste ricevere un messaggio di output simile al seguente:

● myapp.service - Gunicorn instance to serve myapp
   Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2018-08-04 14:16:03 CEST; 1h 32min ago
 Main PID: 22388 (gunicorn)
    Tasks: 4 (limit: 2304)
   CGroup: /system.slice/myapp.service
           ├─22388 /home/noviello/myapp/myappenv/bin/python3.6 /home/noviello/myapp/myappenv/bin/gunicorn --workers
           ├─22408 /home/noviello/myapp/myappenv/bin/python3.6 /home/noviello/myapp/myappenv/bin/gunicorn --workers
           ├─22409 /home/noviello/myapp/myappenv/bin/python3.6 /home/noviello/myapp/myappenv/bin/gunicorn --workers
           └─22410 /home/noviello/myapp/myappenv/bin/python3.6 /home/noviello/myapp/myappenv/bin/gunicorn --workers

Configurare Nginx

Creare un nuovo file di configurazione di Nginx:
sudo nano /etc/nginx/sites-available/myapp

Incollare le seguenti righe di codice, modificando la voce server_name con il vostro nome dominio e cambiando il nome al vostro socket:

server {
    listen 80;
    server_name tuo_dominio www.tuo_dominio;

    location / {
        include proxy_params;
        proxy_pass  http://unix:/tmp/myapp.sock;
    }
}

Salvare e chiudere il file.

Abilitare il nuovo file di configurazione di Nginx:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled

Verificare la corretta configurazione di Nginx:
sudo nginx -t

Riavviare Nginx:
sudo systemctl restart nginx

Se avete il firewall (ufw) di Ubuntu attivo, sarà necessario aprire le porte necessarie:
sudo ufw allow 'Nginx Full'

Aprire il browser e collegarsi al proprio indirizzo:

http://nome_dominio

Dovresti visualizzare il messaggio: Hello World!

Installare i certificati SSL

Installeremo un certificato SSL valido gratuitamente, utilizzando Let's Encrypt.

Aggiungere il repository Certbot Ubuntu:
sudo add-apt-repository ppa:certbot/certbot

Premere INVIO quando richiesto.

Installare Certbot:
sudo apt install python-certbot-nginx

Avviare Certbot specificando il dominio al quale associare un certificato SSL:
sudo certbot --nginx -d tuo_dominio -d www.tuo_dominio

Vi verrà chiesto di accettare i termini del servizio, inserire un indirizzo email al quale poter essere contattati in caso di necessità ed infine vi chiederà se forzare un redirect verso l'HTTPS di tutte le chiamate.

Aprire il browser e collegarsi al proprio indirizzo:

http://nome_dominio

L'installazione e la configurazione di Flask con Gunicorn ed Nginx su Ubuntu 18.04 LTS è terminata.