Megiteam.pl w swoich dokumentach pomocy proponuje jeden sposób na oddzielenie swojego środowiska Pythona od systemowego, a także na ustalenie wersji Pythona, z jaką ma być uruchamiana aplikacja. Metodą prób i błędów doszedłem do innego, jak mi się wydaje także lepszego, sposobu na osiągnięcie tego celu.
Virtualenv na pomoc
Virtualenv to obecnie najpopularniejszy sposób na wirtualizację środowiska uruchomieniowego aplikacji. Mocno korciło mnie, by go wykorzystać do oddzielenia środowiska aplikacji od Pythona dostarczanego przez Megiteam.pl i w końcu się udało. Potrzebny będzie do tego plik virtualenv.py z dystrybucji źródłowej virtualenv. Kopiujemy go sobie w jakieś poręczne miejsce, np. do ~/.. Potem już idzie normalnie:
~$ mkdir v
~$ python2.5 virtualenv.py v/chrzczone
New python executable in v/chrzczone/bin/python2.5
Also creating executable in v/chrzczone/bin/python
Installing setuptools................done.
~$ cd v/chrzczone/
~/v/chrzczone$ bin/easy_install -U -Z psycopg2 \
Django pytz Babel BabelDjango \
django-registration django-tagging-ng \
django-pagination
Po kilku minutach mamy już swoje środowisko w katalogu $HOME/v/chrzczone. Pozostaje tylko ustawić aplikację tak, żeby wiedziała kto tu rządzi. Do tego służy plik .environment w katalogu aplikacji. Oto jak on wygląda w mojej przykładowej aplikacji o nazwie "chrzczone":
PATH=$HOME/v/chrzczone/bin:/usr/local/python2.5/bin:$PATH
PYTHONPATH=$HOME/v/chrzczone/lib/python2.5/site-packages:/usr/local/python2.5/lib/python2.5/site-packages
Wszystko w tym momencie powinno działać, ponieważ pliki .environment są dołączane kaskadowo i zmienne zdefiniowane w nich nadpisują zdefiniowane wcześniej. Ale jest również lepsza (mniej podatna na błędy) metoda osiągnięcia tego samego — żeby wszystko zagrało wystarczy, że plik .environment będzie zawierał tylko jedną linijkę:
source $HOME/v/chrzczone/bin/activate
(dzięki, Eluś, masz u mnie piwo w Ustroniu).
Ale po co to wszystko?!
A choćby po to, żeby łatwiej można było tym zarządzać, np. przy robieniu deploymentu przy użyciu Pavera. Virtualenv obecnie staje się standardową metodą zapewniania rozdzielności środowisk uruchomieniowych Pythona, dającym tyle izolacji, ile się chce. Jest wygodne i bardzo upraszcza obsługę takiego zwirtualizowanego środowiska, zwalniając z konieczności ręcznego ustawiania zmiennych środowiskowych — wystarczy zaimportować w powłoce skrypt aktywujący środowisko i wszystko jest na swoim miejscu. A jeżeli używa się virtualenvwrapper to rzeczy proste stają się jeszcze prostsze (workon, mmm...).
Poładniało (choć to pewnie kwestia gustu) — to pierwsze, co się rzuca w oczy. Oprócz tego:
-
stałe plany zamiast luźnej konfiguracji, nadal z możliwością dokupienia dodatkowych zasobów
-
VPS-y i dedyki
-
faktury i wreszcie możliwość odliczenia VAT
-
wyższe ceny, niewiele, ale zawsze
Jestem więcej niż zadowolony z usług Megiteam.pl, więc przedłużę u nich abonament na kolejny rok, może w wersji wyższej niż obecna — djangohosting.ch ma fantastyczny support, ale ich serwery sprawiają wrażenie przeciążonych. Chyba skończy się na tym, że przeniosę serwisy do Megiteam, a tam zostawię jedynie jakieś playgroundy i sandboxy, bez publicznego ruchu.
Jeżeli ktoś z moich szanownych czytelników zechce wykupić sobie w Megiteam abonament na usługę hostingową, to uprzejmie proszę wpisać zgoda jako nazwę polecającego. Wpadnie mi parę punktów w programie partnerskim... ;)
Bo polecam z czystym sumieniem.
Dzisiejsze ogłoszenie zasad płatności za Google AppEngine wywołało burzę w małej szklaneczce, jaką jest środowisko ludzi robiących aplikacje na AppEngine:
-
część (wygląda mi to na większość) cieszy się z tego, że może płacić, w tym także z tego, że za 3 miesiące będzie płacić za to, co do tej pory miała za darmo;
-
część (mniejszość) nazywa to po imieniu: vendor lock-in (najpierw skuś, potem zmień zasady i zmuś do płacenia za to, co do tej pory było za darmo).
Wyliczenia przeprowadzane tu i ówdzie (głównie na liście AppEngine) wskazują, że nowe limity będą odczuwalne przez wszystkie co najmniej przeciętnie popularne serwisy, a koszt może być znaczący.
Wysiłek włożony w zrobienie aplikacji, którą można wyjąć z GAE i włożyć na normalny serwer może się opłacić. A już na pewno można przestać myśleć o przenoszeniu aplikacji z normalnej platformy na GAE — to się po prostu nie opłaci.
Google zapowiedziało, że za trzy miesiące zmniejszy darmowe limity na AppEngine, a od 24 lutego można sobie zwiększyć limity, dopłacając (drobne bo drobne, ale zawsze) parę dolarków. Moje aplikacje są w takim stadium, że tak naprawdę mnie to nie będzie dotyczyło, ale zmniejszenie limitów przy jednoczesnym wprowadzeniu opłat jak dla mnie coś oznacza — Google przygotowuje się na przetrwanie kryzysu w IT ograniczając wydatki. Może to być także oznaką tego, że uznali AppEngine za produkt na tyle dojrzały, że można za niego brać pieniądze (choć według mnie jeszcze sporo do tego brakuje). Redukcja limitów jest spora, bo w przypadku ilości przesłanych danych to jest 90% (z 10GB do 1GB/24h), a w przypadku obciążenia CPU 86% (z 46 godzin do 6.5 godziny/24h). Na blog czy inny maleńki serwis to może i wystarczy, ale nie daj Boże żeby ktoś się tym poważnie zainteresował, bo limit się wyczerpie w pół godziny. Biorąc pod uwagę dodatkowo fakt, że Google nie powiadamia o zbliżającym się wyczerpaniu limitów (np. po przekroczeniu 80% któregokolwiek z nich), można się nagle obudzić z ręką w nocniku. Nie zmienia to oczywiście faktu, że tą platformą nadal warto się interesować i nawet w wersji płatnej wciąż jest ciekawą propozycją do budowania aplikacji, choć już nie tak atrakcyjną.
Tak czy inaczej, chwilowo nie zamierzam się tym przejmować, choć trudno przewidzieć, jak sytuacja będzie się przedstawiała za trzy miesiące. Na razie staram się robić moje aplikacje w ten sposób, żeby przeniesienie ich na normalny hosting nie wymagało przepisywania całości (co kosztuje więcej zachodu, niż mogłoby się wydawać, ale o tym innym razem).
Od dziś na AppEngine zniesiono jeden z najbardziej denerwujących limitów (bo zazwyczaj nie można było go kontrolować) - limit tzw. High CPU requests (czyli pików CPU). Do tej pory limit wynosił 2 na minutę, co łatwo było przekroczyć szczególnie gdy występowały jakieś lokalne błędy, np. z dostępem do datastore. Podobne problemy występują okresowo na platformie Google i jak do tej pory dotyczą szczególnie żądań HTTP przychodzących z Europy.
Z innych udogodnień: dopuszczalny czas odpowiedzi wzrósł z 10 sekund do 30 i dopuszczony został rozmiar odpowiedzi i upload zasobów większych niż dotychczasowe 1MB (obecnie limit wynosi 10MB).
Idzie ku lepszemu, ale jak dla mnie to wciąż mało. :)
Niedawno po prawej stronie pojawiło się kilka obrazków-linków. O ile dwóch z nich nie ma co opisywać, bo same się doskonale opisują, to link do XP-Dev.com wymaga kilku słów opisu (albo tylko tak mi się wydaje).
Jakiś czas temu chciałem się uniezależnić od mojego dostawcy hostingu w dziedzinie utrzymywania repozytorium z kodem tego serwisu (i paru innych przy okazji też). Przeszkadzało mi to, że współdzielenie dostępu do repozytorium polega na forwardowaniu portu przez SSH, jak dla mnie (i dla znajomych, którym chciałem dać dostęp do repozytorium) to mało wygodne. Zacząłem szukać miejsca, gdzie mógłbym sobie potrzymać mój nie-opensource kod, za darmo lub za niewielką opłatą (ale jak piszę niewielką, to naprawdę niewielką — €10 rocznie to była absolutnie nieprzekraczalna granica). Z serwisów za niewielką opłatą właściwie nie dało się niczego wybrać, zwłaszcza, że oferowały mniej, niż każdy z dwóch darmowych serwisów: Assembla i wspomniany wcześniej XP-Dev. Obejrzałem sobie plany w tych dwóch serwisach i o ile Assembla nie ograniczała ilości repozytoriów, to każde repozytorium miało mniejszy limit wielkości, na XP-Dev.com można było mieć 5 repozytoriów po 300MB każde (na Assembli dowolną ilość 200MB). Założyłem sobie konto na XP-Dev.com, poprosiłem o wgranie dumpów moich repozytoriów i gotowe.
Jak się parę tygodni później okazało, wybór był szczęśliwy — Assembla wprowadziła ograniczenie dla darmowych kont polegające na wymaganiu publicznego dostępu do repozytorium. Parę dni później właściciel XP-Dev.com zapowiedział, że nie zamierza wprowadzać takiego ograniczenia i wręcz zaprasza wygnańców z Assembli. Uch, upiekło mi się...
Od tamtej pory pojawiło się kilka udogodnień, z tych, które zanotowałem (bo mają dla mnie pewną wartość utylitarną):
-
unifikacja url-i serwisu i repozytorium;
-
możliwość samodzielnego wgrywania dumpów repozytorium i dumpowania istniejących repozytoriów;
-
zniesienie limitów rozmiaru poszczególnych repozytoriów i limitu ilości repozytoriów, teraz trzeba się tylko zmieścić w 1.5GB.
Jak dla mnie to co najmniej wystarczająco dużo. Jakby ktoś potrzebował, to są tam też jakieś dodatki typu wiki itp., ale nie ma obowiązku używania. I to mi się podoba.
Zdarzyło się tak, że zrobiłem literówkę w urlconfie i stało się, Google zaindeksowało mi stronę pod błędnym url-em. O ja nieszczęsna, ale przecież zdarza się w najlepszej rodzinie. Trzeba było zmontować jakiegoś redirecta. Co prawda Django ma jakąś swoją aplikację do redirectów (django.contrib.redirects), ale przecież nie o to chodzi, żeby Django robiło wszystko, skoro to taka drobnostka — przecież każdy serwer http ma coś do robienia redirectów, Lighttpd nie jest żadnym wyjątkiem. Trochę nad tym posiedziałem (bo orłem z wyrażeń regularnych to ja nie jestem...) i działa jak złoto:
$HTTP["host"] =~ "(^|\.)wmiastowzieci\.pl$" {
url.redirect = (
"/miajsca/$" => "/miejsca/",
)
}
Żeby było ciekawiej (choć to babol i w nowszym lighty będzie zmienione), lighty w tym momencie wysyła 301 (czyli permanent redirect) co akurat w moim przypadku robi dobrze, bo nie zamierzam więcej popełniać tej literówki. :)
Dzisiaj pojawił się problem z pocztą w jednym z moich serwisów na djangohosting.ch. Część serwerów pocztowych odrzucało przesyłki, do części transfer był w dziwny sposób opóźniony, a dla równowagi część serwerów nie zgłaszała najmniejszych problemów. W końcu udało mi się dowiedzieć, że to coś związane z SPF, jaki ma moja domena. I rzeczywiście, po usunięciu rekordu TXT z danymi SPF maile zaczęły docierać do wszystkich. Co prawda w kilku serwisach od razu lądowały w folderze spam, ale lepsze to, niż zwrotka. Zgłosiłem problem wczesnym popołudniem, ale nie biłem piany, bo serwis jest w trakcie wewnętrznych testów, więc jest to właśnie ten czas, kiedy takie rzeczy mają prawo się ujawnić. Właściwie do niczego nie doszliśmy, ale gdy wróciłem do domu i z ciekawości spojrzałem, jak wygląda automatycznie tworzony rekord SPF, to coś mi się nie zgadzało: podobno miał wyglądać inaczej... O 20:29 zgłosiłem nieprawidłowość (jako komentarz do zamkniętego już ticketu, z prośbą o wyjaśnienie, czy te wpisy są ekwiwalentne), a o 20:34 sprawa była załatwiona, instalator domen rzeczywiście dodawał nieprawidłowy wpis SPF.
Fantastyczny support to jest coś, co rekompensuje wszystkie błędy MySQLdb, z którymi muszę się tam zmagać. Gdyby ktoś się zastanawiał, gdzie tanio postawić aplikacyjkę w Django, to polecam djangohosting.ch.
W celach zupełnie edukacyjnych postanowiłem zrobić jakąś aplikacyjkę na Google AppEngine, na początek w Django 1.0 (na próby ujarzmienia WebOb czas przyjdzie później).
Napisałem kawałek kodu, zdeployowałem, co mogę powiedzieć po tych paru godzinach... Django musi zostać mocno okrojone, żeby zadziałało poprawnie. Ograniczenie do 1000 plików na aplikację oznacza, że z samego Django trzeba wywalić wszystko, co niepotrzebne lub nieużywalne, bo samo Django liczy sobie około 900 plików i na aplikację nie zostanie wiele miejsca. Przydaje się AppEngine Helper for Django, dzięki temu jest sporo prościej. django.forms można używać, ale ostrożnie i w razie potrzeby podpierając się google.appengine.ext.db.djangoforms (oryginalne ModelChoiceField nie działa). Modele przypominają modele Django, używa się ich podobnie, ale API nie jest takie samo, więc trzeba uważać. Jeszcze nie rozgryzłem autoryzacji, ale nie wygląda jakoś tragicznie.
W sumie wygląda nieźle, ale praca z takim okrojonym Django jest dość stresująca. It's a challenge, baby. :)
Dosłownie w ostatniej chwili zdecydowałem się na zmianę dostawcy hostingu na djangohosting.ch, pomimo że byłem zdecydowany na coś innego. Po sugestii Thomasa (dzięki!) przyjrzałem się usłudze dokładniej i postanowiłem dać szansę. Wykupiłem najtańszą opcję, wypróbowałem one-click-django-installer i oczywiście zameldowałem się po SSH. Już pierwsze pół godziny sesji przekonało mnie, że jest tam o wiele przyjemniej niż na Alwaysdata — nie ma żadnych myków z przestawianiem $HOME, no i zwiększanie opcji jest bardziej granularne (oddzielnie procesy, porty, pamięć i przestrzeń dyskowa), a cała infrastruktura w dużej mierze przypomina to, co jest na MegiTeam.pl, z paroma udogodnieniami:
-
można uruchomić serwer developerski django i w razie problemów mieć dostęp do pełnego tracebacka;
-
pełna kontrola nad uruchamianiem FastCGI;
-
łatwiejszy dostęp do logów Lighttpd (chociaż jest w nich równie mało, jak w logach nginxa na megiteam).
Ogólnie wygląda to bardzo dobrze, a przy tym jest trochę taniej.