Deploy di una applicazione sviluppata con il framework Django

N.B. Se non si usa uWSGI per lo sviluppo in locale e' opportuno leggere l'introduzione a uWSGI prima di procedere con il deploy di Django

uWSGI e' molto versatile e di conseguenza ci sono molti modi di effettuare il deploy di una applicazione Django.

Ne vedremo alcuni:

self-contained (tutto in una directory)

All'interno della directory /www/nomedominio (ricordatevi di crearla se non esiste) caricate la vostra applicazione e la directory 'django' presente sulla vostra macchina di sviluppo (su un sistema unix sara' dentro /lib/python2.X/site-packages o qualcosa di simile, ubuntu/debian ad esempio usa le directry all'interno di /var/lib/python).

La directory 'django' contiene (ma guarda un po'...) tutti i moduli necessari al funzionamento di django.

Sebbene Django sia presente su tutti i server unbit e' consigliabile utilizzare la propria versione preferita cosi' che in caso di upgrade non vi siano problemi. Questa tecnica vi permette anche di avere piu' applicazioni nell'account che usano versioni diverse di django.

caricate anche lo script wsgi necessario a django (chiamatelo come preferite, ad esempio django_wsgi.py, l'importante e' che abbia estensione.py)

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

(sostituite mysite con il nome della vostra applicazione)

Dal pannello di controllo (nelle opzioni del dominio) abilitate il flag wsgi e nel campo wsgi_script impostate il nome scelto per lo script wsgi (senza estensione, quindi se lo avete chiamato django_wsgi.py dovrete impostare django_wsgi).

Attendete i soliti 30 secondi e la vostra applicazione sara' avviata. Se ottenete un errore di uWSGI sul browser, verificate il file stderr_log nella home.

Ricordate che l'applicazione una volta avviata resta residente in memoria pronta a ricevere nuove richieste, se quindi effettuate modifiche al codice dovrete riavviarla dalla sezione 'Processi' sul pannello di controllo o tramite ssh.

Per il riavvio potete inviare un segnale di KILL che uccidera' brutalmente i vari processi di uWSGI oppure TERM che attendera' il completamente di eventuali richieste in corso.

Se ottenete sul browser un errore di uWSGI e il processo/i corrispondente non sono in esecuzione sul vostro server, allora significa che uWSGI non si e' avviato. Consultate lo stderr_log nella vostra home per conoscerne il motivo.

uWSGI cerca in automatico i moduli python nelel directory di sistema, nelle directory dell'utente dedicate ai moduli python (/lib/python*) e nella directory corrente. La directory corrente e' impostata automaticamente alla docroot. Ecco perche' uWSGI puo' trovare senza problemi i moduli di django caricati nella docroot (/www/nomedominio in questo caso). Se volete caricare i moduli in altre directory potete specificarle nella direttiva wsgi_pythonpath che vedremo piu' sotto.

condividere la versione di django per tutto l'account

Se vi siete affezionati a una particolare versione di django potete evitare di duplicarla per ogni applicazione. E' sufficiente copiarla all'interno di /lib/python2.5/site-packages (o quella corrispondente alla versione di python usata) per renderla disponibile a tutte le applicazioni dell'account.

Un sistema ancora piu' versatile e' il seguente:

create una directory 'DJAGNO_VERSIONS' (o qualche altro nome piu' fantasioso) al cui interno creerete una directory per ogni versione di django (DJANGO_VERSIONS/1.0, DJANGO_VERSIONS/trunk). Nella directory corrispondente caricate la solita directory django. Nelle opzioni del dominio agite sul parametro wsgi_pythonpath in base alla versione che preferite. Se volete utilizzare la 1.0 aggiungete

DJANGO_VERSIONS/1.0

se volete provare l'ultimo trunk svn non ci sara' bisogno di copiare nulla, bastera' modificare il parametro wsgi_pythonpath

I file statici

Evita di far servire a Django/uWSGI i file statici di un applicazione. Il webserver potra' farlo meglio di qualsiasi implementazione. Per 'sganciare' determinate uri (ad esempio /media) da uWSGI elencale nel campo wsgi_off Puoi mappare determinate uri a percorsi fisici usando l'opzione del pannello docroot_mountpoints. Ex.

/media /www/pippo.it/django/contrib/admin/media

Caching

Django fornisce un sistema di caching integrato. Tra quelli disponibili il piu' avanzato e' sicuramente memcached. Puoi acquistare una istanza di memcached, ma valuta se e' opportuno utilizzarla tramite Django o con il sistema integrato della piattaforma Unbit che evita di sprecare preziosi cicli dei tuoi processi delegando la gestione al webserver.

Invio di Email

Come specificato nelle Faq su ogni webserver e' disponibile un servizio SMTP su localhost 25 (senza SSL/TLS) che puoi utilizzare per inviare email dalle tue applicazioni. Attenzione, evita l'utilizzo di /usr/lib/sendmail al posto di smtp in quanto puo' occupare fino a 3 processi per un banale invio. E' importante che le mail inviate da django abbiano un mittente valido quindi imposta sempre correttamente i vari parametri sender/from. Se una mail inviata da Django non arriva e molto probabile che il problema sia li'.

Gestione dei processi

Sono disponibili diversi parametri di uWSGI per gestire i processi permettendogli di aumentarne l'affidabilita'. Se si ha almeno un processo libero si puo' usufruire del process manager (opzione abilitabile dal pannello) che si occupera' di riavviare i vari processi Django che potrebbero chiudersi. Puoi forzare il riavvio di tutti i processi worker (quelli che eseguono Django) inviando al process manager un segnale INT. Questo pero' chiude brutalmente tutte le eventuali richieste in corso. Se non hai fretta, prima di un INT prova a inviare un segnale TERM, se tutto va bene otterrai lo stesso risultato, ma i worker prima di chiudersi completeranno eventuali richieste in corso.

Usare gli Egg

Buona parte dei moduli python di terze parte viene distribuita sotto forma di egg. Il parametro wsgi_pythonpath accetta oltre che directory anche file egg che verranno aggiunti nel path di ricerca.

L'uso di memoria/address space

E' abbastanza comune che durante l'utilizzo i processi aumentino il consumo di address space. Nelle prime fasi di deploy e' opportuno verificare il ritmo con cui l'utilizzo di memoria sale ed eventualmente impostare un numero massimo di richieste che un singolo worker puo' gestire prima di essere riavviato.

I timeout

Esistono 2 timeout rilevanti per una applicazione Django/uWSGI.

Il primo e' il socket_timeout.

Quando apache riceve una richiesta si collega al server uWSGI, invia la richiesta e ne attende i dati. Apache non puo' rimanere in attesa di dati per piu' di socket_timeout secondi. Configura attentamente questo timeout in base al tipo di applicazione. Di norma comunque non c'e' bisogno di modificarlo.

Il secondo timeout e' l'harakiri (facoltativo).

Un motivo comune per cui i siti vanno offline e' perche una particolare richiesta sta tenendo occupati tutti i processi impedendo alle successive di essere servite. Alcune richieste potrebbero addirittura tenere impegnati i procssi per ore a causa di qualche bug. Per aumentare la sicurezza della propria applicazione si puo' impostare un timeout che venga avviato all'inizio di ogni richiesta e annullato alla sua fine. Se scade in corso d'opera il processo viene riavviato riducendo drasticamente l'impatto del problema.

Note

Non preoccuparti se i tuoi processi si riavviano(e meno che non lo fanno dopo ogni richiesta), e' impensabile che restino in esecuzione in eterno, inoltre per aggiornamenti di uWSGI o riavvi del server (necessari ad esempio per aggiornare il kernel) non c'e' altra soluzione ;)

Sara' sempre il webserver a preoccuparsi di avviare la tua applicazione quando serve. Uccidila quindi senza pieta' e rimorsi ogni volta che ne hai bisogno.

uWSGI puo' essere istallato anche fuori dal contesto Unbit, dal sito ufficiale puoi scaricare i sorgenti o i package per il tuo sistema (attenzione Windows non e' supportato e probabilmente non lo sara' mai) ed eseguirlo in locale. E' un buon modo per prendere dimestichezza con un ambiente di deploy se non si e' ancora pratici.

Se la tua applicazione spreca molta memoria, non correre in banca per poi chiederci un upgrade, prima verifica che non stia commettendo qualche errore implementativo nel codice. Correggendolo avrai una applicazione piu robusta e piu' soldi da spendere in altro. ovviamente non e' possibile sempre correggere i leak della propria applicazione, in tal caso esci di nuovo e torna in banca.

Se le modifiche che effettui sul codice sembrano non avere riscontro, accertati di aver riavviato i processi. E' l'errore piu' comune.

Se hai manie suicide puoi eseguire Django su FLUP+UFCGI: HowtoDjangoUFCGI

Infine, per favore, per pieta' e per tutte le divinita' in cui credi, non contattare l'assistenza (soprattutto quella telefonica) per errori dell'applicazione se prima non hai controllato lo stderr_log (o il file a cui hai reindirizzato i log di uWSGI) e lo stato dei processi. Ovviamente se non hai modo di farlo sei giustificato. cercheremo di essere sempre il piu' gentili e comprensivi possibile, ma pensa sempre che meno gravi sull'assistenza inutilmente, migliore sara' il servizio.

HowtoDjango (l'ultima modifica รจ del 2010-01-28 09:27:36, fatta da RobertoDeIoris)