Instalacja django/mod_python na serwerze linuxpl.com

Wprowadzenie

W poszukiwaniu hostingu dla aplikacji napisanej z użyciem Django, natknąłęm się na ofertę firmy Linuxpl.com, która oferuje tani hosting aplikacji działających pod mod_python'em (możliwa jest także instalacja aplikacji pylonsowych). Oferta jest dość interesująca: konto z dostępem via ssh, nieograniczona liczba domen, emaili, baz MySQL, 3 listy mailingowe, Python 2.4, PostgreSQL 8.2 i całkiem użyteczny panel administracyjny za niewielkie pieniądze. Aby cieszyć się dostępem do mod_pythona należy wykupić przynajmniej plan '2gb'.

Środowisko

Organizacja konta jest następująca: w katalogu domains znajdują się katalogi z domenami podpiętymi do konta. W każdym katalogu jest public_html, który będzie dostępny jako / w danej domenie. Public_html domyślnej domeny jest zlinkowany jako ~/public_html i nim będziemy się w przykładzie posługiwać.

Aby mieć porządek na dysku przyjmiemy następującą strukturę katalogów:

~/apps - tutaj trzymamy nasze aplikacje
~/root - tutaj trzymamy lokalne binaria.
~/python - symlink do ~/root/lib/python2.4/site-packages - dla skrótu

Warto dodać /home/twojlogin/root/bin do zmiennej $PATH i /home/twojlogin/root/lib do $LD_LIBRARY_PATH.

Instalacja django i aplikacji jest dość prosta. Bardzo przydatny jest dostęp przez ssh. W innym przypadku trzeba posługiwać sie ftp (co może być szczególnie czasochłonne przy wolnych łączach). A więc do dzieła.

Instalacja Django

Pobieramy archiwum z ostatnią stabilną wersją django (w momencie pisania jest to 0.96) i rozpakowujemy :

wget http://www.djangoproject.com/download/0.96/tarball/
tar -zxf ../Django-0.96.tar.gz

Aby wszystko było po bożemu, użyjemy skryptu setup.py do instalacji (dzięki temu będziemy właścicielami plików .pyc).

cd Django-0.96
python setup.py build

Następnie instalujemy django w katalogu ~/root:

python setup.py install --prefix=/home/twojlogin/root

Jeśli nie mamy jeszcze utworzonego linku /home/twojlogin/python, to możemy to teraz zrobić:

ln -s /home/twojlogin/root/lib/python2.4/site-packages /home/twojlogin/python

Dzięki temu będziemy mieli mniej do pisania (i pomylenia) w konfiguracji. Ponadto możemy dodać /home/twojlogin/python do zmiennej $PYTHONPATH.

Błąd przy walidacji cookies

Dość często spotykanym problemem przy deploymencie aplikacji korzystającej z mod_python są błędne sumy md5 (podobno winna jest temu biblioteka mhash2). Problem objawia się tym, że aplikacja zachowuje się conajmniej schizofrenicznie przy walidacji sesji - stwierdza, że cookie, które sama nadała, jest błędne, a to właśnie przez moduł md5, który jest używany do tworzenia session id i do walidowania ciastka.

Rozwiązaniem jest wprowadzenie kilku poprawek do middleware'a sesji (contrib/sessions/models.py) i do dekoratorów w aplikacji admin (contrib/admin/views/decorators.py). Można to zrobić na dwa sposoby: albo, jak sugeruje ten wpis w wiki django, pozamieniać importy md5 na sha oraz zakresy slices przy wyciąganiu informacji ze stringa sumy (md5 generuje 32 znaki, sha 40 znaków), bądź użyć patcha z tego ticketa. Patch generalnie robi to samo, ale zamiast zamieniać na stałe md5 na sha, importuje moduł hashes (dostarczony w tickecie, a który trzeba umieścić w $PYTHONPATH), który w zależności od ustawień pobiera md5 lub sha. Oba moduły mają podobne api, różnią się (jak wspomniałem wcześniej) długością generowanej sumy kontrolnej, która jest do pobrania przez atrybut .digest_size.

Moduły baz danych

Na serwerze są zainstalowane moduły do MySQLa (MySQLdb) i PostgreSQLa (psycopg2). Jeśli chcesz użyć pysqlite2, musisz skompilować lokalnie samo sqlite oraz moduł pysqlite2. Ze względu na charakter aplikacji webowych polecam jednak użycie bazy MySQL bądź PostgreSQL.

Instalacja aplikacji

Naszą wypieszczoną aplikację kopiujemy do ~/apps/aplikacja i inicjujemy schemat bazy (chyba, że posiadamy zrzut aktualnego schematu bazy z danymi):

cd ~/apps/twojaaplikacja
python manage.py syncdb

Następnym krokiem jest utworzenie w katalogu ~/domains/twojadomena.com/public_html pliku .htaccess:

SetHandler mod_python

# dodatkowe ścieżki do naszej instalacji - bezpieczny odpowiednik PYTHONPATH
PythonPath  "['/home/twojlogin/python', 'home/twojlogin/apps'] + sys.path" 

# wskazujemy ścieżki, w których może być umieszczony moduł handlera, w przypadku, kiedy nie ma go w standardowym sys.path
PythonOption mod_python.importer.path "['/home/twojlogin/python']+ sys.path" 
PythonHandler django.core.handlers.modpython
# poniższą linię odkomentować tylko na czas sprawdzenia instalacji
#PythonDebug On 

# ustawienia naszej aplikacji
SetEnv DJANGO_SETTINGS_MODULE aplikacja.settings 

# konieczne dla zzipowanych paczek .egg
SetEnv PYTHON_EGG_CACHE /tmp/egg-cache

Aby serwować pliki statyczne bezpośrednio przez serwer http (a nie przez django), tworzymy link symboliczny ~/public_html/media, który będzie wskazywał na katalog z plikami statycznymi w aplikacji ~/apps/aplikacja/media.

ln -s /home/twojlogin/apps/aplikacja/media /home/twojlogin/public_html/media

i dodajemy w nim plik .htaccess:

SetHandler None

To wszystko. Możesz sprawdzić, czy aplikacja działa pod twoją domeną. Jeśli chcesz umieścić aplikację w podkatalogu, to wystarczy do niego przenieść plik .htaccess.