{"id":2152,"date":"2022-02-24T20:00:00","date_gmt":"2022-02-24T19:00:00","guid":{"rendered":"https:\/\/www.giannifavilli.it\/blog\/?p=2152"},"modified":"2022-02-22T16:25:32","modified_gmt":"2022-02-22T15:25:32","slug":"python-django-su-webserver-nginx-e-gunicorn","status":"publish","type":"post","link":"https:\/\/www.giannifavilli.it\/blog\/python-django-su-webserver-nginx-e-gunicorn\/","title":{"rendered":"Python Django su WebServer Nginx e Gunicorn"},"content":{"rendered":"\n<p>Supponiamo di avere una <strong>VPS<\/strong>, un istanza Cloud o pi\u00f9 semplicemente un <strong>RaspberryPi <\/strong>che vogliamo utilizzare come web-server per una o pi\u00f9 applicazioni <strong>Python<\/strong> <strong>Django<\/strong>.<\/p>\n\n\n\n<p>L&#8217;articolo tratta la messa online di una web-app <strong>Django <\/strong>tramite un web-server <strong>Nginx <\/strong>servito da <strong>Gunicorn <\/strong>con il supporto di <strong>Supervisor<\/strong>. <\/p>\n\n\n\n<!--more-->\n\n\n\n<div class=\"wp-block-jetpack-markdown\"><h1>HowTo Django servito da Nginx e Gunicorn con Supervisor<\/h1>\n<p>Per questa guida supponiamo di utilizzare un sistema operativo Debian based (Debian, Ubuntu, Raspberry Pi OS, Mint, ecc.) comunque la guida \u00e8 applicabile a tutti gli altri sistemi operativi Linux, quello che cambia sar\u00e0 il Package Manager (apt, yum, pkg, ecc.).<\/p>\n<p>Python Django viene eseguito tramite <strong>virtual environment<\/strong> quindi tutte le librerie, i pacchetti e gli applicativi necessari allo scopo del progetto python sono installati ed eseguiti all&#8217;interno della cartella di progetto, senza compromettere i software originale del web-server.<\/p>\n<p>In questo articolo non viene trattata la parte relativa al database, pertanto viene utilizzato come database SQLite, che \u00e8 il DB di default di una web-app django. In produzione \u00e8 consigliato utilizzare PostgreSQL ma questa operazione richiede un articolo a parte.<\/p>\n<h2>Installazione software propedeutico<\/h2>\n<p>Sul server deve essere installato del software propedeutico per la fruizione della web-app Django. Pertanto se non \u00e8 gi\u00e0 installato dovr\u00e0 essere installato Nginx, Supervisor che serve a verificare il corretto funzionamento di Gunicorn, Python e il package manager pip, il software Python per la creazione delle Virtual Environments, SQLite o PostgreSQL, software per sviluppatori opzionali quali Git, cURL, Certbot (Let&#8217;s Encrypt certificati SSL per HTTPS), editor di testo tipo nano, vi, pico, ecc.<\/p>\n<p>Utilizzare privilegi di <code>root<\/code> o <code>sudo<\/code>.<\/p>\n<ul>\n<li><code>apt install python3 python3-pip python3-venv python3-dev<\/code><\/li>\n<li><code>apt install nginx supervisor<\/code><\/li>\n<li><code>apt install sqlite3<\/code><\/li>\n<\/ul>\n<p>Opzionali<\/p>\n<ul>\n<li><code>apt install curl git nano build-essential<\/code> &#8211; Tool Sviluppo<\/li>\n<li><code>apt install python3-certbot-nginx<\/code> &#8211; Certbot<\/li>\n<li><code>apt install libpq-dev postgresql postgresql-contrib<\/code> &#8211; PostgreSQL<\/li>\n<\/ul>\n<h2>Cartella di progetto<\/h2>\n<p>Creare la cartella che ospiter\u00e0 l&#8217;intero progetto. Essendo una web-app, il webserver fornisce gi\u00e0 una cartella <code>\/var\/www<\/code>. Assegnare alla cartella di progetto i privilegi di lettura\/scrittura\/esecuzione adeguati all&#8217;utente di sviluppo. Supporre che la cartella di progetto sia denominata <code>django-webapp<\/code><\/p>\n<p>Utilizzare privilegi di <code>root<\/code> o <code>sudo<\/code>.<\/p>\n<ul>\n<li><code>mkdir \/var\/www\/django-webapp<\/code><\/li>\n<li><code>chown www-data:users \/var\/www\/django-webapp<\/code> &#8211; <em>www-data<\/em> \u00e8 l&#8217;utente utilizzato dal webserver, <em>users<\/em> \u00e8 il gruppo assegnato di default a tutti gli utenti di un OS Linux, con tutta probabilit\u00e0 l&#8217;utente utilizzato ne fa parte.<\/li>\n<li><code>chmod g+w \/var\/www\/django-webapp<\/code> &#8211; Vengono assegnati privilegi di scrittura al gruppo <em>users<\/em> e quindi all&#8217;utente utilizzato per eseguire le prossime operazioni. Senza questo passaggio con tutta probabilit\u00e0 non sarebbe procedere oltre.<\/li>\n<\/ul>\n<h2>Inizializzazione ambiente Python<\/h2>\n<p>Viene inizializzato l&#8217;ambiente Python utilizzando la <strong>Virtual Environment<\/strong> che conterr\u00e0 tutte le librerie, i pacchetti e gli applicativi utili al progetto.<\/p>\n<ul>\n<li><code>cd \/var\/www\/django-webapp<\/code><\/li>\n<li><code>python3 -m venv venv<\/code> &#8211; Crea la Virtual Environment dentro la cartella <code>venv<\/code> in alternativa pu\u00f2 essere creata direttamente nella radice della cartella di progetto <code>python3 -m venv .<\/code> dove il <code>.<\/code> significa <em>qui<\/em>. Per il resto dell&#8217;articolo supporre che la cartella utilizzata per contenere le variabili d&#8217;ambiente sia <code>venv<\/code>.<\/li>\n<li><code>source .\/venv\/bin\/activate<\/code> &#8211; Variabile d&#8217;ambiente attivata, pertanto ogni operazione di installazione e configurazione di <em>componenti<\/em> Python viene isolata all&#8217;interno di tale ambiente. Per disattivare le variabili d&#8217;ambiente eseguire il comando <code>deactivate<\/code>.<\/li>\n<li><code>pip install --upgrade pip<\/code> &#8211; Aggiornamento di <em>pip<\/em>, opzionale ma raccomandato.<\/li>\n<\/ul>\n<p><strong>TIPS:<\/strong> Se viene utilizzato <em>git<\/em>, configurare con attenzione il <code>.gitignore<\/code> pe evitare di portare sul repository cartelle inutili delle variabili d&#8217;ambiente (<code>venv<\/code>, <code>bin<\/code>, <code>lib<\/code>, <code>share<\/code>, <code>run<\/code>, <code>include<\/code>, ecc.).<\/p>\n<h3>Inizializzazione web-app Django<\/h3>\n<p>Nell&#8217;articolo vengono riportati i passaggi fondamentali per inizializzare un applicazione Django. L&#8217;articolo non tratta eventuali configurazioni e personalizzazioni, per queste \u00e8 bene avvalersi di tutorial o articoli specifici all&#8217;utilizzo di Django Framework.<\/p>\n<ul>\n<li><code>pip install Django<\/code> &#8211; Installa Django Framework. Qualora sia presente un file di pacchetti Python eseguire <code>pip install -r requirements.txt<\/code> mentre per salvare nel file i pacchetti attualmente installati, eseguire <code>pip freeze &gt; requirements.txt<\/code><\/li>\n<li>Creazione del core della web-app. Supporre che il nome della web-app sia <code>mysite<\/code>\n<ul>\n<li><code>django-admin startproject mysite .<\/code> &#8211; web-app creata da zero.<\/li>\n<li><code>git clone git@github.com:digitalocean\/sample-django.git<\/code> &#8211; web-app scaricata da repository git. Applicazione Django base di <em>DigitalOcean<\/em>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>Comandi utili django<\/h4>\n<ul>\n<li><code>python manage.py startapp app<\/code> &#8211; Crea l&#8217;applicazione con la logica Django <em>MTV: Model, Template, View<\/em><\/li>\n<li><code>python manage.py makemigrations<\/code> &#8211; Crea le migrazioni dai modelli e verifica i componenti.<\/li>\n<li><code>python manage.py migrate<\/code> &#8211; Effettua le migrazioni. (Nel caso di tabelle mancanti nel database <code>python manage.py migrate --run-syncdb<\/code>).<\/li>\n<li><code>python manage.py createsuperuser<\/code> &#8211; Crea l&#8217;utente di amministrazione.<\/li>\n<li><code>python manage.py collectstatic<\/code> &#8211; Crea i file statici per gli assets grafici <em>(css, js, img, fonts, ecc.)<\/em>.<\/li>\n<li><code>python manage.py runserver<\/code> &#8211; Avvia l&#8217;applicazione con il web-server interno. Attenzione eseguire solo in fase di sviluppo e per verificare anomalie.<\/li>\n<\/ul>\n<h2>Gunicorn, installazione e configurazione<\/h2>\n<p>Gunicorn \u00e8 un Web Server Gateway Interface (WSGI) Python.<\/p>\n<ul>\n<li><code>pip install gunicorn<\/code> &#8211; Installa Gunicorn<\/li>\n<li><code>gunicorn --bind 0.0.0.0:8000 mysite.wsgi<\/code> &#8211; Avvia l&#8217;web-app Django servita da Gunicorn selezionado il corretto file WSGI.\n<ul>\n<li>Navigare la web-app utilizzando l&#8217;IP del server (assicurarsi che in console non siano presenti errori e che nel file <code>mysite\/settings.py<\/code> sia abilitato l&#8217;accesso all&#8217;host utilizzato).<\/li>\n<li>Terminare il wes-server tramite <code>CTRL+C<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li>(Opzionale) Verificare che nella cartella di progetto sia presente la cartella <code>run<\/code> con all&#8217;interno il file <code>gunicorn.sock<\/code> (<code>run\/gunicorn.sock<\/code>).<\/li>\n<\/ul>\n<p>Creare un file eseguibile denominato <code>gunicorn_start<\/code> all&#8217;interno della cartella <code>venv\/bin\/<\/code>. Questo file \u00e8 \u00e8 lo script Gunicorn dove sono presenti parametri necessari al corretto funzionamento di Gunicorn per essere servito da Supervisor.<\/p>\n<ul>\n<li><code>touch .\/venv\/bin\/gunicorn_start<\/code> &#8211; Crea il file<\/li>\n<li><code>chmod 775 .\/venv\/bin\/gunicorn_start<\/code> &#8211; Imposta permessi di esecuzione sul file<\/li>\n<li><code>nano .\/venv\/bin\/gunicorn_start<\/code> &#8211; Aggiornare il file utilizzando come bozza, da modificare a seconda delle esigenze il seguente codice.<\/li>\n<\/ul>\n<pre><code class=\"language-bash\">#!\/bin\/bash\n\nNAME=&quot;django-webapp&quot;                                        # Nome dell'applicazione\nDJANGODIR=\/var\/www\/django\/django-webapp                     # Cartella progetto Django\nSOCKFILE=\/var\/www\/django\/django-webapp\/run\/gunicorn.sock    # Socket utilizzato per la comunicazione\nUSER=www-data                                               # Utente utilizzato per l'esecuzione (www-data \u00e8 l'utente di default di nginx)\nGROUP=www-data                                              # Gruppo utilizzato per l'esecuzione (potrebbe essere utilizzato users)\nNUM_WORKERS=3                                               # Numero di processi generati da Gunicorn\nDJANGO_SETTINGS_MODULE=mysite.settings                      # File settings utilizzato da Django\nDJANGO_WSGI_MODULE=mysite.wsgi                              # File WSGI utilizzato da Django\n\necho &quot;Starting $NAME as `whoami`&quot;\n\n# Attivazione variabile d'ambiente\ncd $DJANGODIR\nsource .\/venv\/bin\/activate\nexport DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE\nexport PYTHONPATH=$DJANGODIR:$PYTHONPATH\n\n# Crea la cartella run se non esiste\nRUNDIR=$(dirname $SOCKFILE)\ntest -d $RUNDIR || mkdir -p $RUNDIR\n\n# Avvia la web-app Django tramite Gunicorn\n# Configurazione impostata per essere eseguita sotto Supervisor. Non usare --daemon\nexec .\/venv\/bin\/gunicorn ${DJANGO_WSGI_MODULE}:application \\\n  --name $NAME \\\n  --workers $NUM_WORKERS \\\n  --user=$USER --group=$GROUP \\\n  --bind=unix:$SOCKFILE \\\n  --log-level=warning \\\n  --log-file=-\n<\/code><\/pre>\n<ul>\n<li>Testare il file lanciando il comando <code>.\/venv\/bin\/gunicorn_start<\/code> (CTRL+C per uscire successivamente).<\/li>\n<li>Verificare la presenza della cartella <code>run<\/code> con all&#8217;interno il file socket <code>gunicorn.sock<\/code> (<code>run\/gunicorn.sock<\/code>).<\/li>\n<\/ul>\n<p>Disattivare la <strong>Virtual Environment<\/strong> con il comando <code>deactivate<\/code>.<\/p>\n<h2>Supervisor<\/h2>\n<p>Questo applicativo verifica e gestisce il comportamento di Gunicorn e del ciclo di vita della web-app Django come configurato nel file script utilizzato (<code>gunicorn_start<\/code>). Supervisor prevalentemente si occupa di scrivere messaggi di log relativi a Gunicorn legato alla mantenimento della web-ap Django e si occupa di verificarne il comportamento, ne gestisce l&#8217;avvio, effettua il riavvio della web-app in caso di arresti anomali, riavvio del server, ecc.<\/p>\n<p>Per abilitare Supervisor sulla web-app django \u00e8 necessaria la creazione di un file di configurazione e abilitarne l&#8217;utilizzo e avviare il servizio.<\/p>\n<p>Utilizzare privilegi di <code>root<\/code> o <code>sudo<\/code> e disattivare la variabile d&#8217;ambiente  con il comando <code>deactivate<\/code> se ancora abilitata.<\/p>\n<ul>\n<li><code>touch \/etc\/supervisor\/conf.d\/django-webapp.conf<\/code><\/li>\n<li><code>nano \/etc\/supervisor\/conf.d\/django-webapp.conf<\/code> &#8211; Aggiornare il file utilizzando come bozza, da modificare a seconda delle esigenze il seguente codice.<\/li>\n<\/ul>\n<pre><code>[program:django-webapp]\ncommand = \/var\/www\/django-webapp\/venv\/bin\/gunicorn_start                ; comando da eseguire per avviare la web-app\nuser = www-data                                                         ; Utente utilizzato per l'esecuzione (www-data \u00e8 l'utente di default di nginx)\nstdout_logfile = \/var\/www\/django-webapp\/logs\/gunicorn_supervisor.log   \t; Percorso dove scrivere i messaggi di log\nredirect_stderr = true                                              \t; Salva stderr nel file di log\n<\/code><\/pre>\n<p>Abilitare Supervisor sulla web-app con i seguenti comandi<\/p>\n<ul>\n<li><code>supervisorctl reread<\/code> &#8211; Effettua lettura dei file di configurazione di Supervisor nella cartella <code>\/etc\/supervisor\/conf.d<\/code>.<\/li>\n<li><code>supervisorctl update<\/code> &#8211; Aggiorna eventuali modifiche sui file di configurazione.<\/li>\n<li><code>supervisorctl start django-webapp<\/code> &#8211; Supervisor avvia la supervisione sulla la web-app <em>django-webapp<\/em>.<\/li>\n<\/ul>\n<p>Comandi utili di Supervisor<\/p>\n<ul>\n<li><code>supervisorctl status<\/code> &#8211; Verifica lo stato dei programmi gestiti.<\/li>\n<li><code>supervisorctl restart nome-programma<\/code> &#8211; Arresta la supervisione sul programma indicato.<\/li>\n<li><code>supervisorctl tail nome-programma<\/code> &#8211; Stampa in console l&#8217;output della supervisione sul programma indicato.<\/li>\n<\/ul>\n<h2>Configurazione Nginx<\/h2>\n<p>Di seguito viene riportata i passaggi per la configurazione di Nginx utilizzando un <em>vhost<\/em> specifico per la web-app.<\/p>\n<p>Utilizzare privilegi di <code>root<\/code> o <code>sudo<\/code>.<\/p>\n<ul>\n<li>Creare il file di configurazione per la django-webapp.\n<ul>\n<li><code>touch  \/etc\/nginx\/sites-available\/django-webapp<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Abilitare la configurazione della web-app su Nginx.\n<ul>\n<li><code>ln -s \/etc\/nginx\/sites-available\/django-webapp \/etc\/nginx\/sites-enabled\/<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Modificare la configurazione <code>django-webapp<\/code>\n<ul>\n<li><code>nano \/etc\/nginx\/sites-available\/django-webapp<\/code><\/li>\n<li>Utilizzare come spunto le seguenti configurazioni facendo attenzione ai puntamenti dei parametri di <em>upstream<\/em>, <em>location<\/em> e <em>alias<\/em>. Vedi <a href=\"#struttura-finale-della-cartella-di-progetto\">Struttura finale della cartella di progetto<\/a>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre><code>upstream django-webapp {\n  server unix:\/var\/www\/django-webapp\/run\/gunicorn.sock fail_timeout=0;\n}\n\nserver {\n\tlisten 80 ;\n\tlisten [::]:80 ;\n\n\tserver_name django-webapp.tuo-dominio.it;\n\t\n\tclient_max_body_size 32M;\n\t\n\taccess_log \/var\/www\/django-webapp\/logs\/nginx_access.log;\n\terror_log \/var\/www\/django-webapp\/logs\/nginx_error.log error;\n\n    location = \/favicon.ico {\n\t\talias \/var\/www\/django-webapp\/assets\/favicon.ico;\n\t\tlog_not_found off;\n\t\taccess_log off;\n\t}\n\t\n\tlocation = \/robots.txt {\n        alias \/var\/www\/django-webapp\/assets\/robots.txt;\n    }\n    \n    location \/static\/ {\n        alias \/var\/www\/django-webapp\/static\/;\n    }\n\t\n\tlocation \/assets\/ {\n        alias \/var\/www\/django-webapp\/assets\/;\n    }\n\n    location \/ {\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header Host $http_host;\n        proxy_redirect off;\n        if (!-f $request_filename) {\n            proxy_pass http:\/\/django-webapp;\n            break;\n        }\n    }\n}\n<\/code><\/pre>\n<ul>\n<li><code>nginx -t<\/code> &#8211; Verifica le configurazioni di Nginx e stampa eventuali errori<\/li>\n<\/ul>\n<h2>Rifiniture<\/h2>\n<p>Prima di riavviare Nginx e rendere effettive le modifiche \u00e8 necessario eseguire alcuni passaggi opzionali ma che potrebbero essere propedeutici al corretto funzionamento della web-app.<\/p>\n<p>Utilizzare privilegi di <code>root<\/code> o <code>sudo<\/code>.<\/p>\n<ul>\n<li>Assicurazione che i privilegi sui file nella cartella di progetto siano correttamente configurati.\n<ul>\n<li><code>chown www-data:users -R \/var\/www\/django-webapp<\/code><\/li>\n<li><code>chmod g+w -R \/var\/www\/django-webapp<\/code><\/li>\n<\/ul>\n<\/li>\n<li><code>systemctl restart nginx<\/code> &#8211; Riavviare Nginx.<\/li>\n<\/ul>\n<p>Se tutto \u00e8 andato per il meglio, navigando su <code>http:\/\/django-webapp.tuo-dominio.it<\/code> la web-app django dovrebbe essere fruibile.<\/p>\n<h2>Struttura finale della cartella di progetto<\/h2>\n<p>Esempio della struttura riportante i principali componenti della cartella di progetto <code>django-webapp<\/code>. Da tenere presente per la configurazione del virtual host di Nginx, della configurazione di Gunicorn e di Supervisor.<\/p>\n<pre><code>\/var\/www\/django-webapp\/\n\u251c\u2500\u2500 manage.py\n\u251c\u2500\u2500 app\n\u251c\u2500\u2500 assets\n|   \u251c\u2500\u2500 favicon.ico\n|   \u2514\u2500\u2500 robots.txt\n\u251c\u2500\u2500 logs\n|   \u251c\u2500\u2500 nginx_access.log \n|   \u251c\u2500\u2500 nginx_error.log \n|   \u2514\u2500\u2500 gunicorn_supervisor.log.py\n\u251c\u2500\u2500 mysite\n|   \u251c\u2500\u2500 settings.py\n|   \u2514\u2500\u2500 wsgi.py\n\u251c\u2500\u2500 static\n\u251c\u2500\u2500 run\n|   \u2514\u2500\u2500 gunicorn.sock\n\u2514\u2500\u2500 venv\n    \u2514\u2500\u2500 bin\n        \u251c\u2500\u2500 activate\n        \u251c\u2500\u2500 gunicorn\n        \u251c\u2500\u2500 gunicorn_start\n        \u251c\u2500\u2500 pip\n        \u251c\u2500\u2500 django-admin\n        \u2514\u2500\u2500 python\n<\/code><\/pre>\n<h2>Risoluzione dei problemi<\/h2>\n<p>Molti problemi in questo tipo di operazioni sono legati ai permessi sui file, puntamenti errati e ad eventuali errori di sintassi nei file.<\/p>\n<h2>Riferimenti<\/h2>\n<ul>\n<li><a href=\"\">https:\/\/django-project-skeleton.readthedocs.io\/en\/latest\/nginx_vhost.html<\/a><\/li>\n<li><a href=\"\">https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-20-04<\/a><\/li>\n<li><a href=\"\">https:\/\/michal.karzynski.pl\/blog\/2013\/06\/09\/django-nginx-gunicorn-virtualenv-supervisor\/<\/a><\/li>\n<li><a href=\"\">https:\/\/michal.karzynski.pl\/blog\/2013\/10\/29\/serving-multiple-django-applications-with-nginx-gunicorn-supervisor\/<\/a><\/li>\n<li><a href=\"\">https:\/\/medium.com\/@mijlalawan\/deploying-multiple-django-apps-on-a-vps-with-gunicorn-and-nginx-e47edc6bbf60<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<p><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/fvlgnn\/setup-django-web-server\/blob\/main\/nginx-gunicorn\/README.it.md\" data-type=\"URL\" data-id=\"https:\/\/github.com\/fvlgnn\/setup-django-web-server\/blob\/main\/nginx-gunicorn\/README.it.md\" target=\"_blank\">Repository GitHub<\/a><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Supponiamo di avere una VPS, un istanza Cloud o pi\u00f9 semplicemente un RaspberryPi che vogliamo utilizzare come web-server per una o pi\u00f9 applicazioni Python Django. L&#8217;articolo tratta la messa online di una web-app Django tramite un web-server Nginx servito da Gunicorn con il supporto di Supervisor.<\/p>\n","protected":false},"author":2,"featured_media":2193,"comment_status":"closed","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[3,17,72],"tags":[58,85,83,80,60,63,10,81,68,82,61,33,84],"class_list":["post-2152","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-informatica","category-programmazione","category-raspberry","tag-centos","tag-cloud","tag-debian","tag-django","tag-howto","tag-informatica","tag-linux","tag-nginx","tag-programmazione","tag-python","tag-raspberry","tag-ubunut","tag-vps"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.giannifavilli.it\/blog\/wp-content\/uploads\/2022\/02\/webservber_django_nginx_gunicorn.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4SGGs-yI","_links":{"self":[{"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/posts\/2152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/comments?post=2152"}],"version-history":[{"count":0,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/posts\/2152\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/media\/2193"}],"wp:attachment":[{"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/media?parent=2152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/categories?post=2152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/tags?post=2152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}