Coding

Deploy di Django con Apache/httpd e mod_wsgi

Premetto che ho intrapreso una personale crociata nei confronti dei deploy di Django con Apache. Spesso e volentieri mi trovo a dover utilizzare ancora questa modalità di deploy per motivi di forza maggiore.

Partiamo da dei concetti semplicissimi che devono essere dei capisaldi per ogni deploy, i file statici devono essere gestiti da servizi esterni ( ad esempio amazon S3), l’applicazione python deve essere dentro un virtualenv e devono poter convivere più applicazioni web assieme.
Sulle distribuzioni debian based, ubuntu compresa, è possibile installare il mod-wsgi lanciando il comando:

sudo apt-get install libapache2-mod-wsgi-py3

Mentre su Centos e derivate è possibile installare il modulo con:

sudo yum install python36u-mod_wsgi

Una precisazione, nei repository quando non viene specificata la versione di Python, viene assunto che il modulo è per python 2.7.x.
Successivamente, ricordatevi di riavviare Apache/httpd affinchè le modifiche abbiano effetto.

Permessi sui files

Passiamo adesso alla parte più noiosa, quella delle path e dei permessi.
Assumiamo che il vostro progetto di django si chiami test_app ( visto che fantasia!?) ed è installato nella path /home/foo/test_app/ mentre il virtualenv è installato nella path /home/foo/test_app_env/
Per quanto riguarda i permessi, di solito eseguo le seguenti operazioni:

sudo chmod +x /home/foo/test_app_env/

Il chmod + x sulle cartelle permette di entrare ed accedere ai file e cartelle. Successimavamente lancio:

find /home/foo/test_app_env -type d -exec chmod 755 {} \;
find /home/foo/test_app_env -type f -exec chmod 644 {} \;

Con il primo comando setto i permessi sulle cartelle e con il secondo sui file. In teoria adesso dovremmo essere in regola con i permessi.
E adesso il file di configurazione di VirtualHost che è il cuore del deploy di Django con Apache.

Configurazione di Apache per il deploy di Django


Nelle centos solitamente il file è posizionato in /etc/httpd/conf.d/ mentre sulle debian/ubuntu in /etc/apache2/conf.d/sites-available/ e bisogna usare gli script a2ensite e a2dissite

<VirtualHost *:80>  
ServerName foo.apptecsrl.com  

WSGIScriptAlias / /home/foo/test_app/test_app/wsgi.py 
WSGIDaemonProcess test_app processes=5 python-path=/home/foo/test_app:/home/foo/test_app_env/lib/python3.6/site-packages:/home/foo/test_app_env/lib/python3.6 threads=1 
WSGIProcessGroup test_app 
Alias /static/ /home/foo/test_app/test_app/public/static/ 
Alias /media/ /home/foo/test_app/test_app/public/media/ 
 
<Directory /home/foo/test_app/>  
  AllowOverride all  
  Require all granted  
  Options Indexes FollowSymlinks  
</Directory>  
 
</VirtualHost> 

Nota di merito di questa configurazione base, va alle direttive: WSGIDaemonProcess e ServerName.


ServerName specifica a quale nome risponde la configurazione. Quindi digitando foo.apptecsrl.com vi risponderà la configurazione appena creata.
Configurazioni diverse, con ServerName diversi corrisponsono a siti diversi. (Potete testare la configurazione editanto il file hosts)


WSGIDaemonProcess è la direttiva che specifica quanti demoni distinti devono essere creati. Ad ogni demone viene delegata l’esecuzione dell’applicazione wsgi.
test_app è il display-name dei singoli demoni, process=5 specifica il numero dei demoni che saranno avviati, nel nostro caso saranno 5.
python-path è la lista delle path necessarie per avviare la nostra applicazione. Nel nostro caso abbiamo specificato la path dell’applicazione, la site-packages del virtualenv e il binario dell’interprete.
threads=1 specifica il numero di thread che saranno creati da ogni demone per gestire la richiesta.


Ci tengo a precisare che questa configurazione l’ho usata per anni su un e-commerce con un traffico medio/basso, non ho mai avuto problemi di prestazioni, ma mi rendo anche conto che è una configurazione per niente ottimizzata.