Podstawy zarządzania aplikacjami webowymi na serwerze Linuxa

9 lutego 2023
Jakub Rojek Jakub Rojek
Zdjęcie autorstwa Gabrieli Heinzer z Unsplash (https://unsplash.com/photos/4Mw7nkQDByk)
Kategorie: Wdrożenia, Administracja, Podstawy IT, Poradniki

Z pewnością każdy z nas wie, jaki jest stan wiedzy o informatyce i najpopularniejsze rozwiązania IT w naszym kraju. Oczywiście, dominuje system Windows, na odpowiednim przedmiocie w szkole nauczyciele zapoznają nas z elementami pakietu Office, Paintem, czasem jest jakieś programowanie (aczkolwiek na niższych poziomach od niedawna i w "zabawowej" wersji - lepiej jest w szkole średniej) oraz o bezpiecznym poruszaniu się w Internecie (a przynajmniej powinno tak być). Po edukacji komputery są stosowane do zabawy i w końcu do pracy, ale umówmy się - nadal przewagę ma system Microsoftu i nie ma się czemu dziwić, gdyż jest prosty, graficzny i każdy jest do niego przyzwyczajony. Dotyczy to też studentów czy młodych pracowników w branży informatycznej, bo mało osób decyduje się na to, aby regularnie pracować na innym systemie. Czasem ambitna lub nastawiona na wolne oprogramowanie osoba zainstaluje u siebie Linuxa, niektórzy bardziej majętni zdecydują się na macOS (aczkolwiek niekiedy ma to związek z samą marką Apple'a, a nie możliwościami technicznymi), ale jednak okienka są najczęściej spotykane, także u niedoświadczonych programistów. Zresztą u doświadczonych też się zdarza.

Jest to całkowicie zrozumiałe, ale wiążą się z tym pewne konsekwencje. Mianowicie, z racji tego, że (nie bez powodu) większość serwerów stoi na Linuxie i wiele narzędzi programistycznych pochodzi z tego systemu, osoby, które z Pingwinem nie miały wcześniej do czynienia, prędzej czy później będą musiały jakoś nadrobić wiedzę. Na szczęście, pomijając samodzielną naukę, na studiach informatycznych (lub nawet w technikach) istnieją odpowiednie przedmioty, natomiast co jakiś czas dowiaduję się, że jednak nie na wszystkich uczelniach ten temat jest wprowadzany z równą gorliwością. Ba - jeśli program nauczania o to nie zadba, prowadzący jest ciut bardziej leniwy, a student też nie czuje potrzeby pogłębienia swojej wiedzy, to może się okazać, że o Linuxie wie nader niewiele i jeszcze bardziej się go obawia. Potem następuje zderzenie z rzeczywistością i w odpowiedzi na tę sytuację powstał ten artykuł.

Dla kogo jest ten poradnik i o czym opowiada?

Zacznijmy od drugiej części pytania zadanego w nagłówku - ten tekst nie jest kompletnym poradnikiem zarządzania Linuxem z aplikacjami. Sam nie jestem administratorem, tylko programistą (w dodatku pracującym głównie na Windowsie), który siłą rzeczy dość często ma kontakt nie tylko z kodowaniem, ale też wdrażaniem efektów swojego kodzenia na różne serwery czy w innych środowiskach, głównie linuxowych. Wiem jednak, że są to umiejętności, które nie wszyscy nabywają na zajęciach lub przy samodzielnych próbach w domu, a idąc do pracy oraz w pracy grupowej na uczelni liczą na kolegów lub koleżanki. Dlatego ten artykuł jest omówieniem podstaw wdrażania i działania aplikacji na gotowym hostingu z Linuxem. Wiemy bowiem dobrze, że bardzo popularne są serwery wirtualne, które zawierają preinstalowane usługi, możliwe do wykorzystania przy hostowaniu swojej strony. Dzisiaj skupimy się na tym, jak "poradzić sobie" na takim serwerze typu VPS Managed, choć wiedza powinna przydać się też osobom, które mają do dyspozycji zwykły hosting (czyli bez konsoli, wyłącznie z panelem i FTP-em), ponieważ będę starał się tłumaczyć prostymi słowami, jak to wszystko działa. Często odwołam się do przykładu usługi MyDevil.net, choć zastrzegam, że nie jest to reklama.

Jest to zatem tekst dla:

  • młodych programistów, którzy trochę obawiają się wdrożeń lub grzebania na serwerze, nawet bez praw superużytkownika,
  • studentów informatyki, którzy nawet, jeśli mają Linuxa na studiach lub szkole, to nie mieli kontaktu z produkcyjnym wykorzystaniem go na serwerze,
  • pasjonatów programowania, którzy stawiają pierwsze kroki w uruchamianiu czegoś na serwerze,
  • doświadczonych, zaprawionych w boju programistów i administratorów, którzy lubią wytykać błędy autorom poradników.

Z góry mówię, że nie będzie tutaj podstawowych komend Linuxa - nie będę omawiał takich komend jak ls (listowanie folderów i plików), cd (przechodzenie między katalogami), cp (kopiowanie), mv (przenoszenie i zmiana nazwy) itd. Zakładam, że potrzebne polecenia można znaleźć w sieci i nawet wypisać sobie ściągę na kartce lub skorzystać z gotowych przewodników dla nowicjuszy. Tutaj bardziej skupimy się już na wdrażaniu aplikacji i tym, jak sobie poradzić, kiedy np. szef każe nam sprawdzić, dlaczego strona nie działa. Dlatego z góry uprzedzam, że niektóre kwestie będą bardzo upraszczał, aby każdy mógł je zrozumieć, a później ewentualnie zgłębić.

Jeszcze jedna sprawa zanim zaczniemy - jeśli jesteście programistami i myślicie, że ominie Was kontakt z serwerami linuxowymi, to muszę Was zmartwić, ale jesteście w błędzie. Oczywiście, opieka nad taką maszyną należy do obowiązków administratora i to on dysponuje największą wiedzą z tego zakresu oraz potrafi podpowiedzieć dobre rozwiązania, a także odpowiednio skonfigurować środowisko. Tym niemniej, to nie administrator wdraża aplikację, a w mniejszych firmach nie wdrożeniowec czy inżynier DevOps, tylko właśnie programista. W dodatku to koder jest zwykle alarmowany, gdy klient zgłasza, że coś nie działa i trzeba zwyczajnie spojrzeć w logi lub zobaczyć, czy to błąd z oprogramowaniem, z użytkowaniem czy może potrzebne jest zgłoszenie do administratora. Także, młodzi adepci sztuki programistycznej - nie ignorujcie zagadnień serwerowych, bo o ile specjalistami z tego zakresu nie musicie się stać, o tyle pewną podstawową wiedzę powinniście posiadać. Prędzej czy później Wam się przyda lub pozwoli zaoszczędzić czas.

Jak wygląda standardowa sytuacja na serwerze?

Tak, jak pisałem, będziemy dzisiaj głównie rozmawiać o serwerach już z przygotowanymi komponentami, gdzie mamy małe możliwości konfiguracyjne, ale możemy wejść, wrzucić aplikację, zobaczyć ewentalne dane diagnostyczne, wejść do bazy danych itd. Tym niemniej, zarówno w takich środowiskach, jak i tych, które są ustawiane całkowicie przez nas (tzw. VPS Root lub nawet serwery dedykowane) sytuacja z lotu ptaka wygląda podobnie.

Typowa sytuacja na serwerze VPS Managed - użytkownicy uzyskują dostęp przez port 80 lub 443, a programiści przez 21 lub 22. W środku działa serwer HTTP (Apache2 lub NGINX), który korzysta z wirtualnych hostów, a te z kolei prowadzą do konkretnych folderów na dysku serwera. Obok znajduje się system do zarządzania bazami danych.

Serwery zazwyczaj udostępniają użytkownikowi wydzielony fragment systemu plików, gdzie znajduje się wyznaczone miejsce do składowania plików. Klasycznie na Ubuntu Server jest to /var/www lub /var/www/html, ale na takiej udostępnionej wirtualce możemy o tym zapomnieć - zazwyczaj mamy dostęp do swojego katalogu domowego w /home/[nazwa usera] i tam dalej trzeba szukać. Ewentualnie jest to folder w rodzaju /srv lub /storage. Polecam posiłkować się dokumentacją danej usługi, jeśli jest dostępna. Przykładowo, na serwerach udostępnianych przez MyDevil.net pliki stron znajdują się w /home/[nazwa usera]/domains/[nazwa wirtualnego hosta].

O tym, czym są wirtualne hosty, będzie trochę później - na ten moment musimy wiedzieć, że gdy użytkownik chce wejść na stronę internetową znajdującą się na serwerze, to musi znać konkretny adres (domenowy), który wskazuje na nasz serwer, a ten z kolei na podstawie adresu wie, do którego folderu pokierować odbiorcę i skąd pobrać pliki. Robi to poprzez serwer HTTP (aplikację, usługę), który odbiera zgłoszenia i dystrybuuje je lub informuje odbiorcę, że nie może znaleźć danej strony. Taki serwer HTTP dla każdej strony osobno może udostępniać jej zasoby poprzez port 80 (nieszyfrowany HTTP) lub 443 (HTTPS, o ile zapewnimy certyfikat SSL), choć internauta nie musi wprost wpisywać tej liczby. W zależności od potrzeb i możliwości, możemy również wystawiać konkretne strony lub aplikacje serwerowe pod innymi portami, natomiast sami do serwera dostajemy się przez bramę 22 (standardowy port SSH i SCP - o tym za chwilę) lub przez 21 (zwykły FTP, niepolecany, ale czasem jedyny dostepny).

Na serwerze jest też dostępna usługa do zarządzania bazami danych - zazwyczaj jest to MySQL, ale np. MyDevil udostępnia również inne systemy, jak PostgreSQL czy MongoDB. Programista na takich serwerach zazwyczaj może tworzyć bazy danych i odpowiedniego użytkowników przypisanego do nich, a później działać na samych bazach i logować się do nich albo z poziomu konsoli, albo poprzez inny udostępniony interfejs jak np. phpMyAdmin.

Warto może jeszcze wyjaśnić jedną podstawową cechę Linuxa - jeśli w ścieżce widzimy znak slasha (/) na początku, to oznacza, że startujemy od głównego "folderu" systemu plików. W Windowsie jest to C:\, D:\ czy inne oznaczenie, a w Pingwinie właśnie / To może być kluczowa informacja podczas próby odnalezienia się w folderach na serwerze. Tak samo pamiętajcie, że w Linuxie pliki ukryte mają kropkę na początku i wówczas można je wyświetlić poprzez dodanie przełącznika -a do ls (np. ls -la).

Jak dostać się do serwera?

Zacznijmy od kwestii podstawowej - niestety, nie wszystkie serwery udostępniają interfejs konsolowy, czyli dostęp do terminala. Dotyczy to w szczególności tych tańszych usług lub takich, które są stricte kontrolowane przez administratorów na zamówienie. Wówczas do dyspozycji mamy najprawdopodobniej FTP (ang. File Transfer Protocol), a więc protokół do wymiany plików. W takiej sytuacji do serwera można dostać się wieloma programami - ja polecam WinSCP, który pozwala połączyć się nie tylko przez FTP, ale też inne protokoły, co zaraz nam się przyda.

Załóżmy jednak, że jesteśmy w tej komfortowej sytuacji, że mamy dostęp do terminala. Można się do niego podłączyć poprzez inny protokół, popularny SSH (ang. Secure Shell). Jest to interfejs konsolowy, a więc tekstowy i w tej sytuacji wybór programu, który umożliwi nam dalsze działanie jest dość bogaty. Zapewne znacie bardzo popularny i mały PuTTy, który jest dobrym wyborem, ale warto rozejrzeć się za czymś, co daje większe możliwości, jak np. MobaXterm. Także z poziomu Git Basha instalowanego wraz z Gitem na Windowsie można od razu skorzystać z SSH, nie mówiąc już o zainstalowaniu odpowiedniej paczki w samych okienkach.

No dobrze, ale jak to przebiega? Potrzebujemy następujące informacje:

  • adres hosta, czyli po prostu serwera; może być domenowy lub IP,
  • numer portu - dla SSH standardowo jest to 22, ale w niektórych przypadkach może być inny ze względów bezpieczeństwa,
  • nazwę użytkownika, na którego się logujemy,
  • hasło użytkownika, klucz SSH lub certyfikat.

W najprostszym przypadku musimy w konsoli wpisać:

ssh nazwausera@adresserwera

Po tym czekamy na dalsze instrukcje. Na początku najprawdopodobniej zostaniemy poproszeni o potwierdzenie kontynuowania połączenia, a później przyjdzie nam albo wpisać hasło (pamiętajmy, że w większości konsol można wkleić zawartość schowka prawym przyciskiem myszy), albo zidentyfikować się odpowiednim kluczem SSH. Część serwerów bowiem ze względów bezpieczeństwa preferuje logowanie wyłącznie po podaniu odpowiedniego klucza prywatnego, który zwykle jest zlokalizowany w katalogu domowym użytkownika (na jego komputerze) w folderze .ssh, gdzie znajdują się pliki id_rsa oraz id_rsa.pub. Jeśli posiadany klucz prywatny pasuje do klucza publicznego zapisanego na serwerze, to zostaniemy zalogowani. Istnieje też możliwość jawnego podania pliku z kluczem prywatnym lub certyfikatem poprzez przełącznik -i:

ssh -i plikzcertyfikatem nazwausera@adresserwera

Warto również wspomnieć, że sam dostep do terminala może wymagać połączenia się z konkretną bramą VPN - jest to dodatkowe zabezpieczenie, które niekiedy jest stosowane przez administratorów. Należy też wiedzieć, jak podać inny port, jeżeli nie jest to 22 - robi się to poprzez dodanie przełącznika -p [numer portu].

W tym momencie niektórzy mogą pomyśleć "po co mi jakaś durna konsola, skoro hostingodawcy udostępniają ładne graficzne panele". Owszem, wielu usługodawców daje dostęp do interfejsów cPanel, Plesk lub autorskich i w ten sposób wygodnie można zarządzać serwerem, tworzyć bazy danych, wirtualne hosty itd. Jednak mimo to warto zaprzyjaźnić się z konsolą. Po pierwsze, umiejętność posługiwania się nią sprawi, że znacznie lepiej zrozumiemy lokalizację i przeznaczenie poszczególnych elementów w systemie. Po drugie, niektóre operacje są znacznie łatwiejsze do przeprowadzenia w tej formie, jak np. skopiowanie lub usunięcie bardzo dużej liczby plików. Po trzecie, znajomość terminala pozwoli nam działać na każdym Linuxie, a nie tylko na serwerze z konkretnym panelem do zarządzania. Po czwarte, istnieją serwery w ogóle bez dostepu do graficznego interfejsu, gdzie do dyspozycji jest tylko konsola.

Na poniższym zrzucie ekranu można zobaczyć, jak wygląda udane połączenie się przez SSH z serwerem MyDevila, używając hasła. Przy okazji widzimy zastosowanie komendy pwd, która wyświetla bezwzględną ścieżkę katalogu, w którym aktualnie się znajdujemy.

Ekran terminala po zalogowaniu do serwera MyDevila. Najpierw użytkownik jest pytany o hasło, a następnie pojawia się plansza tytułowa w konsoli oraz znak zachęty.

W tym momencie ktoś może stwierdzić, że FTP jest lepszy, bo umożliwia obsługę plików w formie graficznej. I fakt - to jest pewna przewaga tego protokołu. Tylko, że SSH ma podobny mechanizm, który kryje się pod skrótem SCP (ang. Secure File Copy) i działa bardzo podobnie, tylko bezpieczniej. Warto zainteresować się programami typu WinSCP czy ew. Total Commander, które - jak już wspomniałem - obsługują wiele protokołów, przy czym z naszych doświadczeń w Wilda Software pierwsza opcja jest lepsza. Warto pamiętać, że z SCP można też korzystać w konsoli, kopiując pliki z własnego komputera na serwer lub z serwera na nasz komputer - znajomość tych poleceń może być bardzo pomocna.

# skopiowanie pliku file.txt na serwer
scp file.txt user@server:/path/for/copied/file

#skopiowanie pliku file.txt z serwera na swój komputer do bieżącego katalogu (oznaczanego poprzez kropkę)
scp user@server:/path/for/file/file.txt .

#skopiowanie zawartości folderu wraz z podfolderami
scp -r files/* user@serwer:/path/for/directory/

Przy okazji widzimy, że w systemie Linux kropka (.) oznacza bieżący katalog, a gwiazdka (*) to najprostsze wyrażenie regularne opisujące całą zawartość danego katalogu. Do zapamiętania jest jeszcze podwójna kropka (..) jako poprzedni katalog, a także tylda lub falka (~), czyli katalog domowy danego użytkownika.

Czym są porty?

Hola, hola - piszemy sobie tutaj o portach, ale być może niektórzy nie wiedzą, czym one są. Jeśli wyobrazicie sobie serwer jako średniowieczne miasto ukryte za murami, to porty są bramami do tego miasta. Krótko mówiąc, są to "wejścia" na serwer lub "wyjścia" z niego dla konkretnych usług. Niektóre porty są standardowe, jak np. 80-tka czy właśnie 22, a inne (szczególnie te o wyższych numerach) są do wykorzystania przez własnoręcznie napisane programy lub wręcz efemeryczne (a więc tymczasowe, używane na potrzeby różnych operacji).

Prosta zasada brzmi, że im mniej portów jest otwartych przez serwer na zewnątrz, tym bezpieczniejszy on jest. Zauważmy, że im więcej bram udostępnimy, tym łatwiej atakującemu znaleźć miejsce, którym może w nieuprawniony sposób wejść do systemu plików. Dlatego administratorzy niezbyt chętnie dają możliwość wystawiania dowolnych portów, choć niekiedy jest to możliwe, zwłaszcza po omówieniu sytuacji pomiędzy programistami a osobą zarządzającą serwerem. Zazwyczaj taka potrzeba istnieje w momencie, kiedy usługa nie jest udostępniana przez serwer HTTP. Pamiętajmy też, że czymś innym jest otwarcie portu, a czymś innym otwarcie go na zewnątrz.

Najbardziej popularne porty, z którymi programiści mają do czynienia, to:

  • 21 - FTP
  • 22 - SSH
  • 25 - SMTP (protokół wysyłania poczty elektronicznej, choć zazwyczaj korzysta się z portów 465 i 587)
  • 80 - HTTP
  • 143 - IMAP (jeden z protokołów do pobierania poczty elektronicznej; drugi to coraz rzadziej używany POP3)
  • 443 - HTTPS
  • 3306 - MySQL
  • 5432 - PostgreSQL

Oczywiście, istnieje możliwość przydzielenia innego portu standardowej usłudze (jak zwykle robi się dla wspomnianego wyżej SMTP), choć jest to zawsze w gestii osoby mającej większe uprawnienia na serwerze. W ten sposób można próbować zamaskować standardowe porty, aby dodatkowo zmylić atakującego lub uruchomić jedną usługę wiele razy (np. dwa serwery bazy danych). Podaję to jednak bardziej jako ciekawostkę, gdyż na większości serwerów programiści nie mają takiej potrzeby.

Czym jest serwer HTTP?

Wspomnieliśmy już sobie o istnieniu takiego czegoś jak serwer HTTP. Dla przypomnienia - jest to aplikacja działająca w tle jako usługa, która obsługuje żądania HTTP i wie, do której aplikacji webowej je kierować. Technicznie można powiedzieć, że to właśnie ten element otwiera porty 80 i 443. Programista zazwyczaj nie konfiguruje tego serwera samodzielnie - czyni to administrator, który jest w tym biegły i ma odpowiednie uprawnienia. Osoby kodujące mają zazwyczaj możliwość tworzenia wirtualnych hostów, które są "widziane" przez serwer HTTP i ustawianie pewnych "bezpiecznych" parametrów, np. poprzez pliki .htaccess. Podobnie zresztą jest z PHP, którego konfiguracja też jest przygotowywana przez administratora, ale pozwala na pewną dowolność z punktu widzenia programisty.

Na większości hostingów znajduje się jeden z dwóch najpopularniejszych serwerów HTTP:

  • Apache2 - serwer o nieco prostszej budowie, zazwyczaj uznawany za prostszy, na który można wpływać poprzez pliki .htaccess z poziomu samych aplikacji.
  • NGINX - serwer trochę trudniejszy w obsłudze, jednak uznawany za bardziej wydajny.

Oczywiście, to nie są jedyne opcje - istnieje jeszcze microsoftowy IIS, a sam serwer HTTP może być uruchomiony bezpośrednio przy danej aplikacji, gdyż otwarcie portu dla stron internetowych może przebiegać programistycznie. Tym niemniej, tego na serwerach się nie praktykuje poza szczególnymi przypadkami.

Wiedza o tym, jaki serwer HTTP jest zainstalowany w systemie, jest kluczowa dla programistów z tego powodu, że może wymagać od nich ściślejszej lub luźniejszej współpracy z administratorem w celu ustalenia prawidłowej konfiguracji. W przypadku gotowych usług serwerem jest zazwyczaj Apache2 z uwagi na dostępność plików .htaccess, które programista może samodzielnie przygotować. Choć, co ciekawe, taki MyDevil udostępnia NGINX z opcją czytania tych "nieswoich" plików konfiguracyjnych.

Warto może jeszcze powiedzieć o jednej rzeczy - co zrobić, kiedy z różnych powodów nie jesteśmy pewni, który serwer HTTP działa na naszej maszynie? Jeśli możemy wyświetlić jakąkolwiek stronę internetową lub plik z tego serwera, to łatwo to sprawdzić w narzędziach deweloperskich przeglądarki, zerkając na nagłówek odpowiedzi o nazwie "Server". Poniżej widać, że strona wildasoftware.pl korzysta z NGINX-a.

Fragment narzędzi deweloperskich Google Chrome otwartych na stronie wildasoftware.pl. Prezentowany jest jeden z nagłówków odpowiedzi, w którym widać \

Prosto można też sprawdzić konfigurację PHP - wystarczy utworzyć plik z rozszerzeniem .php o następującej treści i otworzyć go potem w przeglądarce:

<?php phpinfo(); ?>

Jak dostać się do bazy danych?

Dostęp do bazy danych jest bardzo zależny od charakterystyki serwera, natomiast zazwyczaj jest możliwy poprzez konsolę, wyznaczony interfejs graficzny (np. phpMyAdmin) lub - rzadziej - poprzez wystawienie dostępu na zewnątrz, dzięki czemu można podłączyć się bezpośrednio ze swojego komputera z ulubionego programu. Na przykładzie MySQL-a, wejście do bazy danych przez konsolę wygląda zazwyczaj następująco:

mysql -u user -p databasename

W przypadku kiedy możemy dostać się do bazy danych z innego komputera, należy dodać przełącznik -h dbaddress. Domyślnie jest to localhost.

Jednymi z częstszych operacji, które przeprowadza się na bazie danych, jest tworzenie jej kopii zapasowej oraz odtwarzanie jej z pliku SQL. W MySQL służą do tego polecenia:

mysqldump -u user -p databasename > backupfile.sql
mysql -u user -p databasename < backupfile.sql

Dla PostgreSQL sytuacja wygląda dość podobnie, choć jednak widać różnice przy tworzeniu kopii.

psql -U user -d databasename
pg_dump -E UTF-8 -f backupfile.sql -U user -d databasename
psql -U user -d databasename < backupfile.sql

Jak robi się wdrożenie?

Odpowiedź brzmi: to zależy od projektu. Bo rzeczywiście tak jest - w zależności od technologii, możliwości na serwerze oraz przyzwyczajeń programistów można to czynić np. na takie sposoby:

  • ręcznie wgrywając pliki projektu (niepolecane, ale czasem konieczne),
  • umieszczając archiwum ZIP z danymi na serwerze i rozpakowując go skryptem,
  • spushowanie zmian na wyznaczoną gałąź oraz serwer (w kontekście Gita).

Na wielu serwerach, na których dostępna jest konsola, można korzystać z drugiego sposobu, a więc spakować zbudowaną aplikację do jednej paczki, którą się wgrywa przez SCP (jest to szybsze niż kopiowanie wielu mniejszych plików), a następnie za pomocą specjalnie przygotowanego skryptu Basha rozpakowuje się pliki i odpowiednio je "układa" w docelowej lokalizacji. Nie jesteśmy jednak w stanie tutaj przedstawić uniwersalnej procedury wdrożeniowej, natomiast jest kilka rzeczy, o których musi wiedzieć początkujący programista.

Po pierwsze, na serwerze należy umieszczać zbudowaną wersję aplikacji. Pod tym pojęciem może się kryć wdrożenie faktycznie stworzonych plików docelowych, jak np. ma to miejsce w Angularze lub w Javie (plik .war), a może być to też po prostu folder z plikami, okrojony o rzeczy potrzebne tylko przy programowaniu lub zależne od komputera programisty (np. aplikacja w PHP bez plików cache'a itd.). Ponieważ przygotowywanie plików do wgrania za każdym razem może być męczące i człowiek często o czymś zapomni, faktycznie warto utworzyć sobie skrypt, który zrobi to za nas.

Po drugie, większość frameworków oferuje możliwość definiowania środowisk (ang. environments). Przydaje się to do odpowiedniego sparametryzowania aplikacji w zależności od tego, na którym serwerze jest uruchamiana - na komputerze programisty, serwerze testowym lub produkcyjnym. Ważne jest to, aby pamiętać o włączeniu odpowiedniej konfiguracji w danym miejscu - często silnik ma przygotowane odpowiednie komendy do tego. Jest to też istotne z takiego powodu, że w przypadku szukania błędu należy sprawdzić także aktywne środowisko, szczególnie w sytuacjach "u mnie działa, a na serwerze nie" - pamiętajmy, że zazwyczaj środowiska testowe mają pewne parametry ustawione mniej restrykcyjnie, natomiast na produkcji wszelkie błędy są już nie ostrzeżeniami, tylko faktycznie błędami, a dodatkowo zapewne zarówno PHP, MySQL, jak i inne komponenty mają atrybuty konfiguracyjne ustawione na wyższym poziomie bezpieczeństwa i wydajności. Należy mieć to na uwadze i w miarę możliwości starać się ujednolicić serwery, aby pewne błędy mogły pojawiać się wcześniej, podczas testów i tym samym na produkcję trafiały już bezproblemowo działające aplikacje.

Jak edytować plik tekstowy?

Wbrew pozorom, żarty z Vi/Vima nie są wcale wyssane z palca. Tutaj ponownie pojawia się temat szkolenia na uczelni i słowa z zajęć na drugim semestrze, które utkwiły mi w pamięci: jeśli umiecie poruszać się po Vi, to poradzicie sobie na każdym serwerze. I rzeczywiście, jest to prawda, bo praktycznie każde środowisko ma dostępny co najmniej ten edytor. I zgodnie z żartami sprawia on problemy większości ludzi. I nie, nie chodzi o Vi z League of Legends.

A prawda jest taka, że wystarczy opanować kilka skrótów, aby umieć przeprowadzić podstawową edycję. Jeśli chcecie opanować Vi lub Vima (wzbogaconą wersję, którą polecam stosować) perfekcyjnie, to faktycznie jest to długotrwały proces, natomiast do normalnego korzystania wystarczy:

  • I (duża litera "I") - przenosi do trybu wprowadzania, w którym można edytować tekst.
  • ESC - wychodzi z trybu wprowadzania.
  • /phrase - wyszukanie wystąpień danego ciągu znaków, pomiędzy którymi można potem przechodzić poprzez "n".
  • :linenumber - przejście do konkretnej linii.
  • G (duża litera "G") - przejście na koniec pliku (użyteczne przy przeglądaniu logów).
  • gg (dwie małe litery "g") - przejście na początek pliku.
  • :%s/foo/bar/g - zamienia wszystkie wystąpienia frazy "foo" na "bar".
  • :q - normalne wyjście z edytora.
  • :q! - wyjście z edytora bez zapisu.
  • :w - zapisanie zmian.
  • ZZ (podwójne duże "Z") - zapisanie zmian i wyjście z edytora.

A jak w ogóle wchodzimy do edytora? Bardzo prosto:

vim file

#lub

vi file

Warto również pamiętać, żeby otworzyć plik z odpowiednimi uprawnieniami - może się okazać, że po wprowadzeniu wielu zmian na końcu okaże się, że cały czas działaliśmy w trybie do odczytu, gdyż nie użyliśmy sudo (o czym za chwilę). Dlatego należy na to zwracać uwagę.

Oczywiście, istnieją też inne sposoby edycji pliku. Na wielu serwerach dostępny jest potencjalnie prostszy edytor Nano, a zawsze istnieje też możliwość przejścia do edycji pliku w postaci graficznej poprzez WinSCP.

Pamiętajmy też, że nie zawsze konieczna jest edycja pliku - czasem wystarczy samo podejrzenie jego zawartości. Można to zrobić na różne sposoby:

  • cat file.txt - po prostu wypisanie zawartości pliku na ekran.
  • tail -n NUM file.txt - wypisanie ostatnich NUM linii pliki na ekranie. Przydatne szczególnie przy przeglądaniu długich logów.
  • less file.txt - wyświetlenie zawartości pliku, ale we fragmentach, pomiędzy którymi przenosimy się za pomocą spacji.

Uprawnienia i jak korzystać z sudo

Powiedzmy sobie jasno jedną rzecz - na przeważającej części serwerów programista nigdy nie dostanie praw superużytkownika, a już tym bardziej roota, a więc głównego zarządcy systemu. Żaden administrator nie pozwoli na to, aby inna osoba techniczna miała prawa np. zmieniać usługi i tym samym mieć możliwość spowodowania awarii serwera lub instalacji niedozwolonego oprogramowania. To jak najbardziej słuszne podejście, gdyż od tego jest admin, aby dbać o serwer, a nie może tego robić, gdy ktoś mu "przeszkadza". Zamiast tego użytkownicy dostają dostęp do wybranych fragmentów systemu, programów i konkretnych poleceń.

Tym niemniej, na niektórych maszynach także programiści mają prawa superużytkownika, przy czym kluczowe jest stwierdzenie "mają prawa" - to nie jest to samo, co bycie rootem. Aby wykonać komendę z takimi uprawnieniami, wystarczy wcześniej dodać sudo oraz podać hasło:

sudo cp /var/logs/nginx .

Jeśli tylko jest to możliwe, polecane jest stosowanie notacji z sudo na początku, a nie jednokrotne przelogowanie się poprzez sudo su. Co prawda, za każdym razem trzeba wpisywać te 5 znaków na początku więcej, ale w zamian za to ograniczamy sobie pole do popełnienia pomyłki.

O samym roocie nie będę się rozpisywał, gdyż jest to zwykle "zakazany rejon" dla programistów. Powiem tylko tyle - jeśli potrzebujecie o nim informacji, gdyż rzeczywiście na nim działacie, to najprawdopodobniej Wasze potrzeby i wiedza wykraczają poza zakres tego artykułu.

Warto tutaj też wspomnieć o tym, jak zbudowane sa uprawnienia w Linuxie. Aby to wyjaśnić, posłużymy się przykładem - oto zawartość pewnego folderu wylistowana za pomocą polecenia ls -l:

Wynik działania komendy

Przy każdej pozycji po lewej widać ciąg dziesięciu znaków. To właśnie rzeczone uprawnienia i należy je odczytywać następująco:

  • pierwszy znak pokazuje, czy jest to folder - wówczas znajduje się tam literka "d", choć może też być "l" dla linków symbolicznych, a więc "skrótów" do plików,
  • kolejne trzy znaki (od 2. do 4.) to prawa do odczytu (r), zapisu (w) i uruchomienia (x) dla użytkownika będącego właścicielem - jeśli jest myślnik, to dane prawo nie zostało nadane,
  • znaki od 5. do 7. dotyczą tego samego, ale dla grupy, do której należy użytkownik,
  • ostatnie znaki (od 8. do 10.) dotyczą uprawnień innych użytkowników.

W tym momencie niektórzy mogą przypomnieć sobie np. takie polecenia:

chmod 0664 file.txt

To jest właśnie nadanie konkretnych praw, przy czym są one tutaj zapisane w systemie ósemkowym, oznaczając kolejne wartości w sposób numeryczny: odczyt (r) to 4, zapis (w) to 2, a uruchomienie (x) to 1. Co za tym idzie - powyższe polecenie nada prawa do odczytu i zapisu dla właściela oraz grupy (dwie szóstki, 4 + 2) oraz wyłącznie prawo do odczytu dla innych użytkowników (czwórka). Zero na początku oznacza zastosowanie systemu ósemkowego. Uprawnienia można też nadawać za pomocą samych liter (np. g-w), ale pominiemy ten fragment, aby dodatkowo nie namieszać. Podobnie jak temat samych właścicieli oraz grup.

Jak odczytać, co się dzieje?

Jeśli dzieje się coś złego, to zazwyczaj pierwsze, co się sprawdza, to logi. Przy czym warto wiedzieć o tym, że logi mogą być gromadzone na różnych poziomach:

  • aplikacji - znajdują się w folderze z aplikacją w lokalizacji zależnej od samego frameworka. Np. w Yii 2.0 jest to folder runtime/logs w danej podaplikacji, a w Laravelu storage/logs.
  • serwera HTTP - osobno swoje logi gromadzi Apache2 lub NGINX i często znajdują się one w odpowiednim folderze w /var/logs. Jednak, ponieważ zazwyczaj użytkownik nie ma do niego dostępu, często skrót do folderu z logami jest też widoczny w katalogu domowym użytkownika.
  • PHP - sam interpreter PHP również dysponuje swoimi logami, które odnotowują przypadki złego użycia języka pod kątem składniowym, a niekoniecznie pomyłki wynikającej z błędnego wykorzystania frameworka. Także w tym przypadku warto patrzeć do /var/logs.

Oczywiście, wiele usług systemowych generuje logi, także baza danych. Tym niemniej, powyższe są najczęściej monitorowane i stanowią źródło bezcennych informacji.

Domeny i wirtualne hosty

Wspomnieliśmy wyżej kilkukrotnie o wirtualnych hostach i przyszedł czas, aby wyjaśnić to pojęcie.

Nasz serwer zazwyczaj ma jeden adres IP i mimo że sie nim jawnie nie posługujemy (zazwyczaj istnieje jakiś adres domenowy wskazujący na serwer, np. sX.mydevil.net, serwerXXXXXX.home.pl itd.), to pod spodem i tak w końcu gdzieś ten adres IP się pojawi, choćby wtedy, gdy "spingujemy" serwer (wpisując w konsoli ping [adresdomenowy]). Natomiast wpisując tego IP-ka w przeglądarkę lub nawet adres domenowy serwera, najczęściej nie uruchomimy naszej strony. Dlaczego? Ponieważ na jednej maszynie znajduje się zwykle kilkadziesiąt stron i trzeba być bardziej konkretnym we wskazywaniu, o którą nam chodzi. To trochę tak, jakbyśmy przyszli do recepcji szpitala i powiedzieli, że chcemy się widzieć z pacjentem. Kluczowe pytanie brzmi: "z którym".

Może być tak, że adresy "strona1.pl" oraz "strona2.pl" wskazują na ten sam serwer (o tym jak to się robi - za chwilę). Zatem wpisując oba adresy w dwie karty przeglądarki, odpytujemy tak naprawdę tę samą maszynę, która serwuje nam odpowiednią stronę w zależności od adresu. Dzieje się to właśnie dzięki temu, że na poziomie serwera HTTP ten może mieć zdefiniowane ściezki w postaci wirtualnych hostów - wówczas umie rozpoznać, że pod "strona1.pl" powinien kierować żądanie do odpowiedniego katalogu z plikami. W tym przypadku zatem numer odpowiedniego pokoju z pacjentem to wirtualny host.

A w jaki sposób serwer wie, że to do niego kierowane jest pytanie po wpisaniu "strona1.pl"? Zacznijmy od tego, że "strona1.pl" to tak zwany adres domenowy lub mówiąc prościej - domena. Jest kupowana niezależnie od serwera i im bardziej atrakcyjna, tym potrafi być droższa. Kluczowe jest to, że z każdą domeną związane są rekordy DNS (ang. Domain Name Server), które właśnie wskazują na odpowiedni adres IP, czyli nasz serwer. Po edycji rekordów DNS muszą one zostać rozpropagowane pomiędzy innymi serwerami, co może zająć od 30 minut do nawet dwóch dni. A zatem jedna część konfiguracji to odpowiednie przekierowanie domeny (co często robi klient, a jeśli jednak programista, to musi uzyskać dostęp do panelu kontrolnego domeny), a drugie - utworzenie "ścieżek" na samym serwerze, aby serwer HTTP wiedział, jak pokierować żądanie. Może też być tak, że dwa lub więcej adresów są przekierowywane na ten sam folder z aplikacją, a dopiero tam funkcjonalność jest różna w zależności od adresu pytającego.

Istnieją też subdomeny - są to niejako podkatalogi domen, ale w przeciwieństwie do tych znanych z folderów na dysku, tutaj wystąpują na początku. Czyli np. subdomeną dla "strona1.pl" może być "admin.strona1.pl" lub "panel.strona1.pl". Jest to bardzo praktyczne i eleganckie rozwiązanie, które upraszcza zarządzanie domeną i pozwoli oszczędzić pieniądze. A już na pewno jest prostsze w konfiguracji niż ścieżki po slashu, a więc "strona1.pl/admin" czy "strona1.pl/panel".

Uruchamianie procesów w tle

Jeśli na serwerze linuxowym użyjemy komendy ps (lub w bardziej zaawansowanej formie ps alx), to zobaczymy procesy, które są uruchomione. Zazwyczaj zobaczymy tam samego Basha (a więc usługę odpowiadającą za terminal) oraz inne pozycje, zależne od naszych uprawnień. W ten sposób można też się zorientować, czy czasem jakiś proces nie "wisi" i nie powoduje problemów.

Jednak to, co nas interesuje, to fakt, że czasem konieczne jest uruchomienie jakiegoś programu bezpośrednio z linii komend, z pominięciem serwera HTTP czy innej usługi serwującej. Pozostaje pytanie, jak to zrobić, aby aplikacja działała w tle, ale nie blokowała terminala. Tutaj warto też przypomnieć, że nie jesteśmy ograniczeni do jednej konsoli - jak najbardziej można uruchomić ich kilka w różnych kartach. Jednak warto wiedzieć, jak to zrobić inaczej.

Jednym ze sposobów jest wykorzystanie skrótu klawiszowego CTRL+Z oraz używanie komend bg oraz fg. Tym niemniej, prostszą metodą wydaje się użycie komendy nohup, która nie tylko uruchamia proces w tle, ale także zbiera logi do pliku nohup.out. Przykład:

nohup symfony server:start

Więcej sposobów i ich dokładniejsze omówienie możecie znaleźć pod tym linkiem.

Cron

Niektóre zadania powinny być wykonywane okresowo. Zajmuje się tym Cron, a więc program, który działa w tle i co minutę przegląda wpisy w swojej tablicy w celu sprawdzenia, czy powinien wykonać określoną komendę. Można go skonfigurować w Linuxie poprzez polecenie uruchamiające zawartość w preferowanym edytorze tekstowym (np. Vimie):

crontab -e

W ten sposób możemy dodawać kolejne zadania, wskazując czas lub częstotliwość ich wykonania. Przykładowo wpis:

30 1 * * * echo "1" > file.txt

spowoduje wpisanie "1" do pliku file.txt codziennie o 1:30 w nocy. Poszczególne znaki z pierwszych pięciu kolumn należy odczytywać kolejno jako: minutę, godzinę, dzień miesiąca, numer miesiąca, dzień tygodnia. Jak możecie się domyśleć, gwiazdka oznacza dowolną wartość (a więc każdą). Istnieje jeszcze opcja użycia ukośnika, np. poprzez wpisanie */5 - będzie to oznaczać wykonanie co 5 minut, godzin, dni lub miesięcy, w zależności od miejsca.

Wyrażenia Crona mogą sprawiać trudności, szczególnie początkującym adeptom programowania. Dlatego warto posiłkować się wiedzą z Internetu, np. dzięki takim prostym tutorialom.

Jak się uczyć?

A skoro o zdobywaniu wiedzy mowa, to warto wiedzieć, gdzie szukać pomocy, w razie gdyby młody programista utknął z konkretną komendą.

W Linuxie zaimplementowany jest podstawowy podręcznik widoczny pod poleceniem man (od manual). Jeśli dodamy do tego konkretną komendę (np. man cp), to uzyskamy stronę pomocy, na której zostanie nam zaprezentowana składnia komendy oraz dostępne przełączniki. Taką samą zawartość możemy odszukać w sieci, np. tutaj. Jest to bardzo przydatna funkcja, gdy wiemy, czego chcemy użyć, ale nie wiemy, jak dokładnie to zrobić.

Czasem jednak faktycznie nie możemy dojść do tego, jakim sposobem powinniśmy wykonać daną rzecz. W takim układzie pozostaje nam skarbnica wiedzy w postaci Internetu i wszelkich forów, artykułów z poradami czy serwisów typu Stack Overflow. To żaden wstyd szukać - większy problem może pojawić się próbie zrozumienia różnych dróg osiągnięcia danego celu, natomiast to przychodzi z doświadczeniem.

Natomiast to, co jest najważniejsze, to nie bać się próbować. I nie oznacza to brawury oraz wykonywania niepewnych komend na serwerze na zasadzie "jakoś to będzie". Mam na myśli to, że warto od czasu do popracować na testowej instancji systemu Linux i dobrze wiemy, że w tym celu nie trzeba instalować tego systemu bezpośrednio na swoim komputerze - istnieją maszyny wirtualne oraz rozwiązania w rodzaju WSL, dzięki czemu można korzystać z namiastki Pingwina nie mając go w pełni zainstalowanego. A to daje naprawdę dużą wiedzę i obycie z systemem - trzeba tylko chcieć.

Podsumowanie

Ten artykuł nie wyjaśnił wszystkich aspektów utrzymywania aplikacji na udostępnionym nam serwerze linuxowym - doskonale o tym wiem. Nie ma tutaj np. definiowania firewalla, konfigurowania serwera HTTP, wgrywanie kluczy publicznych użytkowników, konteneryzacji, wyrażeń regularnych itd. Jednak celem tekstu nie było przedstawienie pełnego kompendium wiedzy dotyczącego zarządzania serwerem, bo zwykle i tak do wielu funkcji taki użytkownik nie ma dostępu. Dodatkowo, z jednej strony technologie, w których powstaje oprogramowanie, a także usługi hostingodawców różnią się kształtem na tyle mocno, że nie ma sensu rozpatrywać każdej dostępnej możliwości. Z drugiej - zbyt dużo wiedzy mogłoby przytłoczyć młodych programistów, a to dla nich pisany był tekst.

Mam nadzieję, że ten poradnik pozwolił nadać pewien kierunek w rozumieniu tego, co tak naprawdę dzieje się na serwerze, na którym stoi aplikacja Waszego zespołu. Celem było to, abyście mogli poczuć się pewnie i faktycznie efektywnie poruszać po zakamarkach systemu plików oraz pomiędzy usługami. Oczywiście, należy mieć świadomość, że to zaledwie wierzchołek góry lodowej - zagadnień jest znacznie więcej i wraz z każdym projektem oraz serwerem wiedza będzie tylko rosnąć. Czego Wam szczerze życzę.

Pozdrawiam i dziękuję - Jakub Rojek.

Lubimy pisać, nawet bardzo, ale na co dzień tworzymy aplikacje webowe i mobilne. Sprawdź niektóre z wykonanych przez programów.

O autorze

Jakub Rojek

Główny programista i współwłaściciel Wilda Software, z wieloletnim doświadczeniem w tworzeniu i rozwoju oprogramowania, ale także w pisaniu tekstów na różnorakich blogach. Zaprawiony w boju analityk i architekt systemów IT. Jednocześnie absolwent Politechniki Poznańskiej i okazjonalny prowadzący zajęcia na tej uczelni. W wolnych chwilach oddaje się graniu w gry wideo (głównie w karcianki), czytaniu książek, oglądaniu futbolu amerykańskiego i e-sportu, odkrywaniu cięższej muzyki oraz wytykaniu innym błędów językowych.

Jakub Rojek