Sprawa wygląda prosto. W mojej dystrybucji, Arch Linuksie, tworzenie nowych pakietów nie stanowi zbyt dużej trudności. Dlaczego więc nie załadować wszystkiego do własnego zestawu pakietów, który mógłbym później wykorzystywać jednocześnie na komputerze stacjonarnym i laptopie, tym samym zapewniając sobie identyczne środowiska na obu maszynach? W ostatnich dniach porobiłem kilka eksperymentów z pakowaniem i rezultaty są obiecujące, choć nadanie temu wszystkiemu jakiegoś szlifu to zabawa na co najmniej kilkanaście wieczorów.
Początki
W typowej dystrybucji Linuksa albo jakimś kombajnie rzecz wygląda prosto. Dostajemy PHP, MySQL, serwer WWW i programik do uruchamiania wszystkiego jednocześnie. Ja jednak potrzebowałem czegoś o wiele bardziej rozbudowanego. Najbardziej bolała mnie niemożność przetestowania tego samego skryptu na różnych wersjach PHP. Pewnego dnia usiadłem, wywaliłem w diabła Apache'a, wstawiłem w jego miejsce Lighttpd, a całość połączyłem z własnoręcznie skompilowanym PHP przy pomocy FastCGI. Dodatkowo, aby nie odtwarzać przy każdej akualizacji wszystkich opcji kompilacyjnych, napisałem prosty skrypt w Bashu do wywoływania polecenia ./configure/ ze wszystkim, co potrzeba. Niebawem zorientowałem się, że zabawa opcjami + rozmnożenie instancji FastCGI pozwoli mi uruchomić parę interpreterów PHP równocześnie, a co ważniejsze - podpiąć je wszystkie do jednego serwera i przypisać do różnych lokalnych subdomen. Voile'a, pomyślałem, iście genialny pomysł. Po godzinie prób i eksperymentów udało się. Do serwera podłączone były dwa warianty PHP pracujące w uprawnieniach innych użytkowników. Paręnaście minut później dołączył do nich trzeci, tym razem w wersji 5.3-dev, a po nim 6.0-dev. Te włączane już były na żądanie, aby nie przymulać niepotrzebnie komputera, gdy nie są potrzebne. Każdy projekt otrzymał trzy subdomeny, po jednej dla każdej wersji PHP, dzięki czemu przez prostą modyfikację adresu URL mogłem sprawdzać zachowanie się skryptu na różnych wersjach. Tak narodziło się nietypowe środowisko do testowania skryptów...
Założenia
Po pewnym czasie zacząłem dostrzegać pewne niedoskonałości takiej chałupniczej kompilacji. Bałagan w plikach konfiguracyjnych, niedziałający instalator PECL w wersjach 5.3 i 6.0 oraz super-długie ścieżki do ich interpreterów to tylko niektóre problemy, które powoli coraz bardziej zaczęły mnie wkurzać. Normalną koleją losu, po etapie badawczo-rozwojowym przyszedł czas na ogarnięcie przedsięwzięcia... sporządziłem listę założeń:
- Możliwość testowania skryptów na różnych wersjach PHP równocześnie.
- Współpraca zarówno ze środowiskiem WWW, jak i konsolowym.
- Prawidłowa współpraca z repozytoriami PECL i PEAR.
- Relatywnie prosta aktualizacja.
- Porządnie rozplanowana konfiguracja.
- Zestaw aplikacji narzędziowych typu phpMyAdmin odpalany na dodatkowej instalacji PHP będącej częścią środowiska roboczego.
Jakie pakiety musi objąć system?
Podstawowym elementem są pakiety z interpreterami:
- PHP narzędziowe - ma być stabilne, nastawione na wsteczną kompatybilność i niewypluwanie tysięcy KB błędów, pracujące na prawach serwera WWW. Służyć ma do odpalania phpMyAdmina oraz jemu podobnych narzędzi. Znajdować się w nim mają wyłącznie potrzebne moduły.
- PHP testowe - na nim działać mają tworzone przez programistę skrypty. Tutaj musimy już mieć dużą ilość modułów ładowanych dynamicznie, działający PECL oraz konfigurację wolną od historycznych naleciałości. Każda gałąź PHP posiada oddzielny pakiet, np. php52, php53, php60.
Wszystkie wersje muszą się instalować z interfejsami CLI oraz CGI wraz z towarzyszącym i odpowiednio skonfigurowanymi skryptami startowymi. Aby nie wchodziły sobie w paradę, binarki dostają prefiks z numerem wersji, pozwalający je przy okazji odróżnić od siebie. Wywołanie php zarezerwowane jest dla narzędziowej wersji.
Okazuje się jednak, że przy tej okazji warto przyjrzeć się też samemu Lighttpd. Domyślny pakiet musi uwzględniać różne zastosowania i pełno w nim zupełnie nieprzydatnych z naszego punktu widzenia dodatków w rodzaju MySQL-owych wirtualnych hostów czy zaawansowanych usług autoryzacyjnych. Tak więc całość odchudzamy oraz przy okazji dodajemy już instalowanie wyjść umożliwiających podpięcie się pod konkretne elementy katalogu domowego użytkownika.
Dostęp serwera do plików
Z plikami i uprawnieniami sytuacja prezentuje się następująco. Serwer WWW pracuje na swoich własnych prawach i ma swój własny katalog domowy. Do niego przypisane są programy narzędziowe. Jednocześnie ja, jako użytkownik, mam w swoim katalogu domowym foldery Projekty i Web. Pierwszy to właściwe projekty, drugi to różne bzdety w rodzaju maleńkich skrypcików oraz poligon doświadczalny dla skryptów ściąganych z sieci. Jestem właścicielem wszystkich plików w tych dwóch katalogach.
Ponieważ korzystamy z FastCGI, interpretery mogą swobodnie pracować na prawach innego użytkownika, niż serwer WWW. Na prawach serwera odpalamy jedynie narzędziowe PHP, zaś reszcie przydzielamy samych siebie. Pojawia się jednak problem. Pomimo faktu, że taki php52 wykonuje się z uprawnieniami zyxist:users, to Lighttpd w dalszym ciągu musi zająć się sprawdzeniem, czy zażądany skrypt w ogóle istnieje w systemie plików. Nie może tego zrobić jawnie, gdyż katalog /home/zyxist ma uprawnienia 0700, ergo nikt inny nawet nie może zobaczyć czy coś jest w środku. Tu z pomocą przychodzi polecenie mount z magiczną opcją --bind. Do pliku /etc/rc.local dopisujemy dwie komendy, które podmontują nam katalogi Projekty i Web również w katalogu domowym Lighttpd, dzięki czemu nie będą dotyczyć ich uprawnienia nałożone na /home/zyxist:
mount --bind /home/zyxist/Web /home/lighttpd/web mount --bind /home/zyxist/Projekty /home/lighttpd/projects
Po stronie Lighttpd wszelkie odwołania do katalogów naszych skryptów muszą iść przez te drugie ścieżki. Cała ta operacja w dalszym ciągu nie zmienia przynależności naszych plików. Dopóki nie wpiszemy sobie do uprawnień czegoś innego niż "4" lub "5" na drugiej i trzeciej pozycji, w dalszym ciągu nikt nam tam nic nie będzie w stanie zapisać, a co najwyżej odczytać - ponadto nawet do tego musi być zalogowany albo jako my sami, albo jako lighttpd. Cała reszta to odpowiednie zabezpieczenie dostępu poprzez przeglądarkę oraz rozsądne racjonowanie dostępu do komputera - wszak najsłabszym ogniwem zabezpieczeń zawsze pozostanie człowiek.
Zapakowanie tego wszystkiego w pakiety jest dość skomplikowane. Z jednej strony, bez informacji, pod jakiego użytkownika trzeba się podpiąć, instalator nie jest w stanie zbyt wiele zrobić, z drugiej - raczej należy unikać sytuacji, by instalator pakietu wstrzymywał się w oczekiwaniu na wpisanie przez użytkownika jakiejś wartości z klawiatury. Można to jednak rozwiązać, dopisując stosowną sekcję inicjalizującą do skryptu startowego Lighttpd. Przy pierwszym uruchomieniu sprawdzi on konfigurację - jeśli jej nie będzie, wysypie się, jeśli będzie - dokończy instalację i odpali serwer WWW.
Pozostałe sprawy
Ostatnia rzecz to dobór pozostałych programów narzędziowych. Tu wytypowałem następujący zestaw tego, co mi jest potrzebne:
- phpMyAdmin - do zarządzania MySQL-em
- phpPgAdmin - do zarządzania PostgreSQL-em
- phpUnit - do testowania
- phpDocumentor - generowanie dokumentacji API
- TypeFriendly - generowanie podręczników użytkownika
- coś do lokalnej obsługi poczty - na potrzeby skryptów, które w trakcie działania muszą wysłać e-mail.
- zestaw dokumentacji - na wypadek awarii Internetu
Zakończenie
Jak widać, robi się nam z tego całkiem rozbudowane środowisko robocze dla programistów PHP. Na chwilę obecną wstępnie zapakowałem Lighttpd oraz jeden z interpreterów, jednak tak jak wspominałem na początku - proces doprowadzenia całości stanu używalności potrwa trochę (tym bardziej, że za tydzień z kawałkiem zaczyna się sesja :)). Przy każdym pakiecie trzeba upewnić się czy działa, czy wszystkie pliki trafiły we właściwe miejsca, czy poprawnie zostały dobrane zależności oraz czy nie brakuje jakiegoś potrzebnego modułu. Niemniej gra jest warta świeczki. Archa na pewno jeszcze trochę będę używał, więc myślę, że zrobienie tego raz, a dobrze, oszczędzi mi kłopotów w przyszłości i poprawi produktywność. Paczki w dodatku można upublicznić, być może przydadzą się też komuś jeszcze...






Napisał godlark w sobotę, 30 maja 2009 o 09:59
I właśnie takiego czegoś jak "mount --bind" szukałem.
Dzięki.