{"id":2159,"date":"2022-02-21T17:35:50","date_gmt":"2022-02-21T16:35:50","guid":{"rendered":"https:\/\/www.giannifavilli.it\/blog\/?p=2159"},"modified":"2022-02-22T16:25:43","modified_gmt":"2022-02-22T15:25:43","slug":"python-django-su-webserver-apache-e-wsgi","status":"publish","type":"post","link":"https:\/\/www.giannifavilli.it\/blog\/python-django-su-webserver-apache-e-wsgi\/","title":{"rendered":"Python Django su WebServer Apache e WSGI"},"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>Apache <\/strong>con modulo <strong>WSGI <\/strong>(<strong>mod_wsgi) <\/strong>abilitato. <\/p>\n\n\n\n<!--more-->\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<div class=\"wp-block-jetpack-markdown\"><h1>HowTo Django servito da Apache e WSGI (mod_wsgi)<\/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 Apache e il modulo WSGI per il server web, 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 apache2 libapache2-mod-wsgi-py3<\/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-apache<\/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>Configurazione Apache<\/h2>\n<p>Di seguito viene riportata i passaggi per la configurazione di Apache utilizzando un <em>vhost<\/em> specifico per la web-app. A seconda del sistema operativo utilizzato alcune cartelle potrebbero avere nomi diversi da quelli descritti di seguito. Verificare la documentazione ufficiale del sistema operativo Linux utilizzato.<\/p>\n<ul>\n<li>Disattivare la <strong>Virtual Environment<\/strong> con il comando <code>deactivate<\/code> se ancora abilitata.<\/li>\n<li>Verificare che il modulo WSGI sia installato e abilitato su Apache.\n<ul>\n<li><code>ls -la \/etc\/apache2\/mods-available<\/code> e <code>ls -la \/etc\/apache2\/mods-enabled<\/code> verificare la presenza dei files <code>wsgi.conf<\/code> e <code>wsgi.load<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li>Creare il file virtual host per la django-webapp. Utilizzare privilegi di <code>root<\/code> o <code>sudo<\/code>.\n<ul>\n<li><code>touch  \/etc\/apache2\/sites-available\/django-webapp<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Abilitare il virtual host della web-app su Apache.\n<ul>\n<li><code>ln -s \/etc\/apache2\/sites-available\/django-webapp \/etc\/apache2\/sites-enabled\/<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Modificare il file vhost <code>django-webapp<\/code>\n<ul>\n<li><code>nano \/etc\/apache2\/sites-available\/django-webapp<\/code><\/li>\n<li>Utilizzare come spunto le seguenti configurazioni facendo attenzione ai puntamenti dei parametri WSGI, Directory e Alias. 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>&lt;VirtualHost *:80&gt;\n\tServerAlias django-webapp.tuo-dominio.it\n\t\n\tWSGIDaemonProcess django-webapp python-path=\/var\/www\/django-webapp:\/var\/www\/django-webapp\/venv\/lib\/python3.8\/site-packages\n\tWSGIProcessGroup django-webapp\n\tWSGIScriptAlias \/ \/var\/www\/django-webapp\/mysite\/wsgi.py\n\t\n\t&lt;Directory \/var\/www\/django-webapp\/static&gt;\n\t\tRequire all granted\n\t&lt;\/Directory&gt;\n\n\t&lt;Directory \/var\/www\/django-webapp\/assets&gt;\n\t\tRequire all granted\n\t&lt;\/Directory&gt;\n\n\t&lt;Directory \/var\/www\/django-webapp\/mysite&gt;\n\t\t&lt;Files wsgi.py&gt;\n\t\t\tRequire all granted\n\t\t&lt;\/Files&gt;\n\t&lt;\/Directory&gt;\t\n\t\n\tAlias \/robots.txt \/var\/www\/django-webapp\/assets\/robots.txt\n\tAlias \/favicon.ico \/var\/www\/django-webapp\/assets\/favicon.ico\n\tAlias \/assets\/ \/var\/www\/django-webapp\/assets\/\n\tAlias \/static\/ \/var\/www\/django\/omnia\/static\/\n\t\n\tErrorLog ${APACHE_LOG_DIR}\/django-webapp.error.log\n\tCustomLog \/dev\/null common\n&lt;\/VirtualHost&gt;\n<\/code><\/pre>\n<p><strong>Attenzione<\/strong> Nella dichiarazione di <code>WSGIDaemonProcess<\/code> verificare nelle virtual environment della cartella di progetto la versione di <em>python<\/em> installata e il path dei <em>site-packages<\/em>. Vedi <a href=\"#struttura-finale-della-cartella-di-progetto\">Struttura finale della cartella di progetto<\/a>.<\/p>\n<h2>Rifiniture<\/h2>\n<p>Prima di riavviare Apache 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 apache2<\/code> &#8211; Riavviare Apache.<\/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 Apache.<\/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 mysite\n|   \u251c\u2500\u2500 settings.py\n|   \u2514\u2500\u2500 wsgi.py\n\u251c\u2500\u2500 static\n\u2514\u2500\u2500 venv\n    \u251c\u2500\u2500 bin\n    |   \u251c\u2500\u2500 activate\n    |   \u251c\u2500\u2500 pip\n    |   \u251c\u2500\u2500 django-admin\n    |   \u2514\u2500\u2500 python\n    \u2514\u2500\u2500 lib\n         \u2514\u2500\u2500 python3.8\n             \u2514\u2500\u2500 site-packages\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\/apache2_vhost.html<\/a><\/li>\n<li><a href=\"\">https:\/\/docs.djangoproject.com\/en\/4.0\/howto\/deployment\/wsgi\/modwsgi\/<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<p><strong><a href=\"https:\/\/github.com\/fvlgnn\/setup-django-web-server\/blob\/main\/apache-wsgi\/README.it.md\" data-type=\"URL\" data-id=\"https:\/\/github.com\/fvlgnn\/setup-django-web-server\/blob\/main\/apache-wsgi\/README.it.md\" target=\"_blank\" rel=\"noreferrer noopener\">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 Apache con modulo WSGI (mod_wsgi) abilitato.<\/p>\n","protected":false},"author":2,"featured_media":2161,"comment_status":"closed","ping_status":"open","sticky":false,"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":[74,58,83,80,60,63,10,68,82,61,33,84],"class_list":["post-2159","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-informatica","category-programmazione","category-raspberry","tag-apache","tag-centos","tag-debian","tag-django","tag-howto","tag-informatica","tag-linux","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_apache_wsgi-e1645441692515.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4SGGs-yP","_links":{"self":[{"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/posts\/2159","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=2159"}],"version-history":[{"count":0,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/posts\/2159\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/media\/2161"}],"wp:attachment":[{"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/media?parent=2159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/categories?post=2159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.giannifavilli.it\/blog\/wp-json\/wp\/v2\/tags?post=2159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}