Po przygodach z przenoszeniem aplikacji z Jetty na Tomcata serwer ostatecznie stoi. Jest to całkowicie mój VPSik. Pierwotnie działał na nim Gentoo, jednakże nigdy nie bawiłem się z tą dystrybucją w związku z czym trochę szkoda mi było kilku tygodni na rozkminienie o co w tym wszystkim chodzi. Dlatego też decyzja o zainstalowaniu na nim Debiana, dystrybucji dojrzałej, sprawdzonej i szeroko znanej. No i jak wiadomo – support dla niej to cała rzesza linuxowych geeków.
Wstęp
Cel był prosty – stworzyć system, na którym będą działały moje aplikacyjki. Nie wymaga on zatem tuningowania jak wielkie produkcyjne serwisy, ale podstawowe kwestie dotyczące stabilności oraz bezpieczeństwa wypadałloby na nim zrobić. Docelowo na serwerze miały działać następujące usługi:
- Apache Tomcat
- bazy danych (MySQL na start, potem doinstaluję Postgresa)
- języki skryptowe – choćby do wygodnego używania PHPMyAdmin, czy tego typu rozwiązań
- no i jakiś serwer WWW, by te języki skryptowe mogły gdzieś śmigać
To był plan 0. Otrzymałem Debiana z już zainstalowanym SKD dla Javy, a także ze śmigającym Tomcatem. Instalacja samego kontenera nie jest specjalnie skomplikowana – po prostu ściągamy go poprzez apta i tyle. Jeżeli jednak musimy zaczynać z “gołym” systemem to z pewnością ten link będzie bardzo pomocny. UWAGA!!! Dodam tylko, że występuje tam mały błąd – po instalacji SDK w pliku /etc/profile należy dopisać:
export $JAVA_HOME
Zaś na listingu występuje zapis bez znaczka $. Bez tego nasze aplikacyjki dostarczone z Tomcatem nie ruszą. Wypadałoby też zobaczyć czy na pewno używamy Javy 6. W konsoli:
java -version
Jeśli mamy tam jakieś wersje <1.6 to znaczy, że można też odwiedzić wątek na pewnym forum. Na chwilę obecną zakładam, że wszystko jest dobrze poinstalowane plus używamy najnowszej wersji Javy.
W zależności od potrzeby serwer obsługujemy poleceniami:
/etc/init.d/tomcat-6 start|stop|restart
Konkretna nazwa skryptu może się różnić (w podanym przeze mnie linku jest to /etc/init.d/tomcat). Domyślnie nasz kontener działa na porcie 8080 – jego zmianą zajmiemy się za chwilkę. Uruchamiamy kontener i powinniśmy pod adresem http://localhost:8080 zobaczyć taką oto stronę:

Tomcat jest dostarczany bynajmniej nie jako ‘out-of-the-box’ i trzeba trochę pogrzebać w plikach konfiguracyjnych, aby spełniał w pełni swoją rolę. Domyślnie też jest dostarczany z 2 aplikacjami, które umożliwiają zarządzanie serwerem poprzez interfejs WWW. Pozostawianie ich dostępnych na serwerze produkcyjnym nie jest zbyt dobrym pomysłem (z powodów bezpieczeństwa), ale na etapie stawiania systemu mogą okazać się bardzo przydatne. By jednakże otrzymać do nich dostęp należy edytować plik /var/lib/tomcat6/conf/tomcat-users.xml. U mnie wygląda on tak:
<tomcat-users>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="nasztajnylogin" password="mojetajnehaslo" roles="admin,manager"/>
</tomcat-users>
Oczywiście user i hasło są zmyślone 🙂 W tym pliku XML mamy taki kontenerowy ACL – tworzymy jednocześnie zarówno role jak i użytkowników. Dzięki temu uzyskujemy dostęp do 2 aplikacji zarządzających kontenerem. Są one o tyle istotne na etapie tworzenia serwera, że można szybko i wygodnie poprzez stronę WWW zarządzać serwerkiem. Ja jednakże postanowiłem pobawić się plikami konfiguracyjnymi, zatem usunąłem dostęp do tych aplikacji, a je same wyrzuciłem z serwera.
Baza danych MySQL
Podstawą dla wszystkich aplikacji sieciowych jest baza danych. HowToJava powstała z użyciem MySQLa, podobnie póki co jest i z ProgramBash. Wypadało zatem zainstalować ten RDBMS by mieć na czym operować. W pakietach Debiana znajduje się najnowsza (w miarę) wersja zatem wystarczy użyć apta i jesteśmy w domu. Problemy mogą wystąpić przy próbie połączenia z bazą z zewnątrz – dla przykładu z naszego lokalnego komputera. W moim przypadku Hibernate rzucał wyjątkiem o niemożliwości połączenia się z powodu Connection refused. Innymi słowy – już sam serwer nie chciał mojego requestu. Rozwiązanie jest proste – należy edycji poddać plik /etc/mysql/my.cnf i parametrowi bind-address nie nadawać wartości localhost lub 127.0.0.1, ale IP naszego serwera. Wtedy bez najmniejszych problemów będzie można połączyć się z lokalnej maszyny. Nalezy także pamiętać o utworzeniu użytkownika z odpowiednimi prawami (łączącego się z określonego hosta). Na koniec zabaw ze zmianą uprawnień wydajemy polecenie:
flush privilages;
Bez tego można kląć na potęgę dlaczego nasze zmiany w uprawnieniach nie są widoczne.
Routing lub też proxy jak kto woli
Domyślnie Tomcat (choć dotyczy to w sumie wszystkich serwerów/kontenerów Javy z jakimi miałem okazję pracować) działa na porcie 8080 lub okolicach. Rzecz jasna w przypadku podpinania domeny pod nasz serwer takie rozwiązanie nie za bardzo wchodzi w grę – wszak nie można ustawić w routingu domen docelowego portu. Przyjęło się, że w użyciu mamy port 80 – tam przeglądarki standardowo wysyłają swoje żądania. Cóż zatem zrobić, aby wykupiona domena wskazywała na nasze pliki z aplikacjami Javy (u mnie to WARy) i wyglądało to transparentnie? Mamy kilka rozwiązań:
- ustawienie portu w konfiguracji Tomcata na numer 80. Proste, ale absolutnie niezalecane ze względów bezpieczeństwa!!!
- forwardować ruch poprzez odpowiednią konfigurację firewalla. Iptables to dobre narzędzie do tego.
- postawić nasz serwer/kontener Javowy za zwykłym serwerem WWW, który będzie działał jako proxy.
Powyższe rozwiązania zostały dokładnie omówione w tym miejscu, a i z pomocą Gogla, można dowiedzieć się wszystkiego. Ja również pierwotnie myślałem o postawieniu Apache i zastosowaniu connectorów, jednakże moi mili admini wyperswadowali mi takowy pomysł i stanęło na podobnym rozwiązaniu, ale w oparciu o szybki serwer WWW – nginx. Oficjalna stronka znajduje się pod adresem http://nginx.org/. Sam serwer ma swoje plusy i minusy, by się z nimi zapoznać zapraszam do artykułu w Wikipedii. Sam serwer posłuży też do obsługi PHP – konkretniej do narzędzi zarządzających bazą danych (wygodny jestem), a także być może w przyszłości hostowania tego bloga.
Instalacja nginxa jest banalnie prosta:
sudo apt-get install nginx
I nasz serwerek jest już zainstalowany. Całkiem przyzwoity materiał o tym serwerze można znaleźć u Riklaumina, ja ograniczę się na razie do pierwszego jego uruchomienia. Tuningiem i bliższym poznaniem zajmę się w kolejnych artykułach. Przede wszystkim należy przejśc do katalogu /etc/nginx/conf.d. Cokolwiek znajdzie się w tym katalogu zostanie domyślnie potraktowane jako plik konfiguracyjny. Należy utworzyć nasz podstawowy plik konfiguracyjny:
cd /etc/nginx/conf.d
touch default.conf
Edytujemy stworzony plik i wrzucamy w niego na przykład taki oto kod:
server {
listen 80;
server_name WPISUJEMY_NASZE_IP DOMENA1 DOMENA2 DOMENA3;
# Main location
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 52m;
client_body_buffer_size 128k;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_cache_valid 5m;
}
}
To baaaaardzo podstawowa konfiguracja. Ale na pewno osiągnęliśmy jedno – wszystkie requesty domyślnie lecące na port 80 zostaną przekierowane na port 8080, gdzie będzie na nie już oczekiwał nasz Tomcat. Można odpalić nginxa poleceniem:
/etc/init.d/ngninx start
Być może trzeba będzie po raz pierwszy zrobić to z poziomu konta administratora. Jak widać sam serwer zainstalował skrypt, ktory uruchamia go przy starcie systemu (w katalogu /etc/init.d/).
Tomcata musimy odpowiednio poinformować o istnieniu czegoś takiego jak subdomeny. I tutaj właśnie pobawimy się plikami konfiguracyjnymi (choć będzie to dość szybka zabawa). Docelowo mój serwerek zainstalował się w katalogu /var/lib/tomcat6/. W tymże katalogu znajduje się również podstawowy katalog dla naszych aplikacji – webapps. Dla naszych aplikacji, które zamierzamy wdrożyć należy przygotować pliki dystrybucyjne – ja pozostaję od samego początku wierny plikom WAR. Teraz musimy wyedytować plik konfiguracyjny Tomcata. W naszym ulubioym edytorku bierzemy na tapetę plik /var/lib/tomcat6/conf/server.xml.
<Host name="SUBDOMENA_Z_DOMENA" appBase="webapps/NAZWA_SUBDOMENY" unpackWARs="true" autodeploy="true"></Host>
Restart Tomcata i należy udać się pod powyżej wpisany adres. Oczywiście serwer nie znalazł ani katalogu, ani pliku o wskazanej nazwie (jeszcze nic nie wysłaliśmy na serwer), zatem przekierował nas na główną stronę w domenie. Jednakże póki co wszystko działa poprawnie – nie dostaliśmy od serwerów po drodze błędu 404. Do testów maszyny najlepiej na szybko stworzyć maksymalnie prosty projekt w Javie (ja użyłem przykładowego projektu JSF). Generujemy dla niego plik WAR i łączymy się z serwerem dowolnym klientem FTP/SCP/SSH (w zależności co lubimy i co mamy/odpaliilśmy na serwerze). Przesyłamy do katalogu webapps nasz plik WAR i tworzymy dla niego katalog. Dla ułatwienia stworzyłem subdomenę example.chlebik.pl jak i odpowiedni katalog. Do niego wrzuciłem plik WAR. Uwaga!!! Można naciąć się na uprawnieniach do katalogów lub plików. Podążając tropem aktywności mojego Tomcata wszystkie pliki i katalogi przypisuję do użytkownika tomcat6 oraz grupy o tej samej nazwie. Przynajmniej nie dostaję ukochanego komunikatu – Permission denied.
Powyżej w pliku server.xml ustawiliśmy, że ta konkretna aplikacja ma być deployowana na starcie serwera, a także ma mieć rozpakowany plik WAR (dla zwiększenia szybkości działania). Ponownie odwiedzamy adres naszej subdomeny – i nic. Dalej jesteśmy przekierowywani na główną stronę domeny. Cóż się stało? Ano taka dziwna cecha Tomcata – wystarczy nasz plik WAR znajdujący się (u mnie) w katalogu webapps/example/, przemianować na webapps/example/ROOT.war. Restart serwera i co? Hip-Hop, hurrra. Dostajemy miły komunikat od JSF i Facelets, że nasza aplikacja działa. Można z ciekawości zajrzeć do tego katalogu – został tam rozpakowany w podkatalog o takiej samej nazwie jak plik WAR cały kod naszej aplikacji. Dlaczego w ten sposób? Uważam, że w katalogu z aplikacjami powinny być inne katalogi, a nie stado plików WAR lub inszych, które zaciemniają obraz. Każda aplikacja ma swój katalog i niech w nim dzieje się co chce.
PHP i Fast-CGI
Na koniec został mi do zainstalowania PHP. O ile w przypadku pierwotnie planowanego Apache rzecz jest banalna, o tyle nginx wymaga trochę zabawy. Należy bowiem doinstalować specjalny moduł do obsługi języków skryptowych poprzez Fast-CGI. Tutaj korzysta się z dobroci serwera lighttpd, ale o tym można już poczytać sobie w artykule. Dodam tylko by odpowiednio skroić nasz plik default.conf z nginxa – można połączyć konfig FCGI z PHP z istniejącą konfiguracją, ale można też zastosować podejście opisane w powyższym tutorialu. Co więcej – nginx jest tak fajnym narzędziem, że przy restarcie waliduje swoje pliki konfiguracyjne – jeśli coś jest nie tak wówczas od razu zostaniemy o tym poinformowani bez konieczności przeglądania logów serwera.
Co dalej?
Mam nadzieję, iż trochę ułatwiłem początkującym adminom życie (jakbym ja miał 10 lat doświadczenia :). W ramach możliwości postaram się kontynuować tak mile rozpoczęty cykl wpisów o administracji serwerem dla programistów. Jeśli znalazłeś jakikolwiek błąd w powyższym materiale lub masz jakieś sugestie – rzecz jasna zapraszam do kontaktu lub komentowania. Gdyby ktoś był zainteresowany VPSem lub hostingiem tam gdzie ja to należy pisać na ten adres email. Przy okazji możecie wspomnieć, że to dzięki mnie wiecie o usłudze 🙂
Tak na koniec
Na sam koniec dobra rada dla wszystkich programisto-administratorów 🙂 Jakiekolwiek operacje na sewerze (dedyku, VPSie czy w ogóle czymkolwiek) lepiej wpierw przetestować na VirtualBoxie. Produkt firmy SUN świetnie się do tego nadaje. Nie będę opisywał tutaj procesu instalacji i tak dalej, dam tylko kilka szybkich rad dla uruchamiania wirtualizacji systemu w Windows XP:
1. Używana przestrzeń dyskowa na system linuxowy powinna być wrzucona na partycję z systemem plików innym niż FAT32!! Inaczej dostaniemy błędy podczas instalacji, albo użytkowania, gdyż ten format nie obsługuje istnienia plików powyżej 2 GB.
2. W świetle powyższego – skonfigurować wirtualną maszynę by miała rozszerzalne miejsce na partycji. Często coś tam się doinstaluje, odinstaluje lub chce pobawić i nagle BUM – nie ma miejsca.
3. Jeżeli naszego linuxa instalujemy wraz ze środowiskiem graficznym należy ściągnąć VBoxLinuxAdditions. Jest to obraz płyty, który po instalacji naszego systemu należy podpiąć i następnie uruchomić z poziomu linuxa. U mnie wymagało to doinstalowania kilku rzeczy (nagłówków jądra linuxa i czegoś jeszcze). Kiedy to wszystko już zrobimy uruchamiamy po prostu skrypt .sh dla linuxa i stosownej architektury. Dzięki temu będziemy mogli rozszerzać ekran z wirtualizowanym systemem, grafika przestanie się ciąć i w ogóle będzie lepiej.
4. RZECZ BARDZO ISTOTNA!!! Dość często ludziom zdaża się, że uruchomienie VBoxa nawet z czystą konsolą (bez fajerwerków KDE czy GNOME) powoduje zżarcie przez VBoxa jakiś 50-90% procesora. Strasznie to wkurzające – dzieje się tak niezależnie od przydzielonej ilości RAMu. Rozwązaniem jest wyłączenie antywirusa!! U mnie działa darmowy AVG – jego wyłączenie automatycznie zredukowało zasobożerność VBoxa. Domyślam się, że chodzi o monitorowanie wirtualnego połączenia internetowego. Z tego co wyczytałem w sieci również niektóre fiewalle zachowują się w podobny sposób.