Instalacja LAMP na Ubuntu 24.04 z PHP-FPM
Konfiguracja Apache, MariaDB z unix_socket oraz PHP 8.3 z PHP-FPM na Ubuntu 24.04. Poradnik rozwiązuje błędy wyświetlania kodu źródłowego i pustych stron.
Cel projektu
Stos LAMP składa się z czterech komponentów zainstalowanych na serwerze Ubuntu 24.04: jądra Linux, serwera HTTP Apache, bazy danych MariaDB oraz interpretera PHP 8.3. Po zakończeniu prac skonfigurowany zostanie wirtualny host oparty na nazwie domeny obsługujący katalog aplikacji, baza danych z użytkownikiem o minimalnych uprawnieniach, integracja PHP z Apache poprzez PHP-FPM oraz certyfikat Let's Encrypt.
Proces instalacji obejmuje cztery komendy apt. Większość treści tego poradnika dotyczy konfiguracji połączeń między komponentami oraz eliminacji błędów, które powodują wyświetlanie pustej strony, pobieranie kodu źródłowego przez przeglądarkę lub brak dostępu do nowo zainstalowanej bazy danych. Każdy z tych błędów posiada charakterystyczne objawy, które zostały opisane poniżej wraz z dokładną treścią komunikatów.
Wymagania wstępne i potencjalne problemy
Należy przyjąć, że systemem jest czysty VPS z Ubuntu 24.04 KVM, posiada użytkownika z uprawnieniami sudo lub konto root oraz publiczny adres IPv4. Minimalny stos usług wymaga 1 GB pamięci RAM; zaleca się przydzielenie 2 GB przed instalacją aplikacji korzystającej z bazy danych, ponieważ domyślne bufory MariaDB oraz procesy PHP-FPM szybko zużywają pierwszy gigabajt.
Przed uruchomieniem Certbot muszą zostać spełnione dwa warunki. Wymagana jest domena z rekordem A wskazującym na publiczny adres IP serwera VPS — Let's Encrypt dokonuje weryfikacji przez HTTP dla tej nazwy, a sam adres IP nie pozwala na uzyskanie certyfikatu. Porty 80 i 443 muszą być dostępne z internetu, co u wielu dostawców wymaga otwarcia ich w firewallu sieciowym w panelu administracyjnym oraz w ufw na serwerze. Propagacja zmian DNS może trwać do jednej godziny, dlatego należy najpierw skonfigurować rekord A.
Step 1 - Install Apache and confirm the default page
sudo apt update
sudo apt install -y apache2apt automatycznie uruchamia i włącza usługę. Należy to sprawdzić:
systemctl status apache2W wyniku należy otrzymać linię active (running). Następnie należy otworzyć http://YOUR_SERVER_IP/ w przeglądarce. Wyświetlenie strony Apache2 Ubuntu Default Page z napisem "It works!" oznacza poprawną konfigurację — nie jest to błąd. Strona ta znajduje się pod adresem /var/www/html/index.html i jest obsługiwana przez domyślny wirtualny host 000-default.conf. Oba elementy zostaną później wyłączone; obecnie ich obecność jest pożądana.
Jeśli strona się nie ładuje, mimo że systemctl wskazuje, że proces działa, przyczyną jest firewall. Kolejnym krokiem jest jego konfiguracja.
Krok 2 - Otwarcie firewall dla HTTP i HTTPS
Pakiet apache2 rejestruje trzy profile aplikacji ufw. Wyświetl listę:
sudo ufw app listZostaną wyświetlone Apache, Apache Full oraz Apache Secure. Apache obejmuje tylko port 80, Apache Secure obejmuje tylko port 443, natomiast Apache Full obejmuje oba porty — jest to wymagany profil, ponieważ w kolejnym kroku zostanie dodany TLS.
sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
sudo ufw enableZezwól na ruch OpenSSH przed uruchomieniem ufw enable. Domyślnie ufw blokuje cały ruch przychodzący. Włączenie usługi bez reguły SSH spowoduje natychmiastowe przerwanie połączenia — bieżąca sesja pozostanie aktywna, ale ponowne połączenie nie będzie możliwe. Potwierdź za pomocą sudo ufw status; wartości dla OpenSSH, Apache Full oraz ich odpowiedników v6 muszą wynosić ALLOW.
Step 3 - Instalacja i zabezpieczanie MariaDB
sudo apt install -y mariadb-server
systemctl status mariadbSystem Ubuntu 24.040 zawiera MariaDB 10.11 (wersja LTS), zatem nie jest wymagane dodawanie zewnętrznego repozytorium. Po uruchomieniu usługi należy przeprowadzić jej zabezpieczanie:
sudo mysql_secure_installationZaleca się uważne czytanie komunikatów zamiast wielokrotnego naciskania klawisza Enter. W przypadku pytania o current root password, należy nacisnąć Enter — hasło nie zostało jeszcze ustawione. Na pytanie "Switch to unix_socket authentication?" należy odpowiedzieć n, ponieważ ta metoda jest już domyślnie włączona w tym pakiecie. Na pytanie "Change the root password?" należy odpowiedzieć n (powód opisano w następnym akapicie), a na pozostałe pytania odpowiedzieć Y: usunięcie anonimowych użytkowników, zakaz zdalnego logowania na konto root, usunięcie bazy testowej oraz przeładowanie tabel uprawnień.
Poniższy fragment jest najczęstszym źródłem nieporozumień. W MariaDB na systemie Ubuntu konto bazodanowe root wykorzystuje uwierzytelnianie unix_socket, a nie hasło. Oznacza to, że baza danych ufa użytkownikowi systemu operacyjnego, którym został użytkownik. Dzięki temu poniższa komenda działa z poziomu powłoki root:
sudo mysql...i przenosi użytkownika do promptu MariaDB [(none)]> bez konieczności podawania hasła. Ta sama komenda uruchomiona przez użytkownika bez uprawnień zostanie odrzucona. Jest to celowe działanie: dostęp do konta root bazy danych jest powiązany z sudo w systemie, co eliminuje ryzyko kradzieży, phishingu lub ataków brute-force na hasło. Metoda ta jest bezpieczniejsza od hasła, dlatego nie należy jej zmieniać. Wynika z tego następująca zasada: nigdy nie należy konfigurować aplikacji przy użyciu konta root. Należy utworzyć dedykowanego użytkownika dla każdej aplikacji (Step 7), ponieważ aplikacje łączące się przez TCP przy użyciu nazwy użytkownika i hasła nie mogą korzystać z uwierzytelniania socket, a każda aplikacja powinna mieć dostęp ograniczony tylko do własnej bazy danych.
Krok 4 - Instalacja PHP 8.3 wraz z PHP-FPM
Domyślna wersja PHP w systemie Ubuntu 24.04 to 8.3. Należy zainstalować menedżer procesów FPM oraz rozszerzenia wymagane przez typowe aplikacje:
sudo apt install -y php8.3-fpm php8.3-mysql php8.3-cli \
php8.3-curl php8.3-xml php8.3-mbstring php8.3-zipNależy zwrócić uwagę na to, czego nie ma na tej liście: libapache2-mod-php. Ten starszy pakiet osadza interpreter PHP w każdym procesie Apache. Rozwiązanie to jest proste, ale każdy proces worker zawiera kopię PHP, niezależnie od tego, czy obsługuje skrypt, czy statyczny obraz. Oba procesy mają wspólny cykl życia, a rozwiązanie to działa wyłącznie z MPM prefork w Apache — najmniej wydajnym modułem. PHP-FPM działa jako oddzielna pula procesów, z którą Apache komunikuje się przez socket. Dzięki temu Apache może używać wątkowego MPM event do obsługi plików statycznych i przekazywać do puli wyłącznie żądania PHP. Pula ta jest konfigurowana niezależnie od serwera WWW, a ta sama konfiguracja FPM zadziała w przypadku użycia nginx jako proxy. Jest to obecnie standard ze względu na wysoką wydajność.
Apache komunikuje się z FPM poprzez moduł proxy_fcgi. Należy go włączyć, aktywować konfigurację dostarczoną przez pakiet FPM i zrestartować usługę:
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo systemctl restart apache2a2enconf php8.3-fpm aktywuje /etc/apache2/conf-available/php8.3-fpm.conf, który zawiera regułę przekierowującą pliki PHP do socketu FPM. Kluczowa reguła dopasowuje każdy plik .php i przekazuje go do socketu pod adresem /run/php/php8.3-fpm.sock:
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>Pliku tego nie należy edytować; jest on poprawny domyślnie. Znajomość ścieżki socketu jest jednak niezbędna do późniejszej diagnostyki błędów typu "PHP pobiera plik zamiast go uruchomić" oraz "Primary script unknown". Oba błędy wynikają z braku zgodności między Apache a FPM w kwestii tego socketu lub pliku docelowego.
Step 5 - Virtual host oparty o nazwę dla aplikacji
Virtual hosting oparty o nazwę pozwala jednemu adresowi IP obsługiwać wiele witryn; Apache wybiera witrynę na podstawie nagłówka Host: w żądaniu. Należy utworzyć katalog dla aplikacji, z dala od domyślnego /var/www/html:
sudo mkdir -p /var/www/testapp
sudo chown -R www-data:www-data /var/www/testapp
sudo chmod -R 755 /var/www/testappWłasność plików jest istotna. Apache oraz PHP-FPM działają na Ubuntu jako użytkownik www-data, zatem pliki, które serwer WWW musi odczytywać — oraz katalogi, do których aplikacja musi zapisywać dane, jak folder uploads — powinny należeć do www-data. Jeśli pliki mają być również edytowane przez zalogowanego użytkownika, powszechną praktyką jest nadanie własności plikom i dodanie użytkownika do grupy www-data; w przypadku standardowej instalacji najbezpieczniejszym rozwiązaniem jest www-data:www-data.
Utwórz virtual host w /etc/apache2/sites-available/testapp.conf:
<VirtualHost *:80>
ServerName app.example.com
DocumentRoot /var/www/testapp
<Directory /var/www/testapp>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/testapp-error.log
CustomLog ${APACHE_LOG_DIR}/testapp-access.log combined
</VirtualHost>Ustaw ServerName na swoją rzeczywistą domenę. Parametr Options -Indexes zapobiega listowaniu zawartości katalogu przez Apache w przypadku braku pliku index — w przeciwnym razie użytkownicy mogą przeglądać strukturę źródeł. Parametr AllowOverride All umożliwia działanie pliku .htaccess, który jest wymagany przez większość aplikacji PHP do obsługi przyjaznych adresów URL; można usunąć ten parametr w None w celu uzyskania niewielkiego wzrostu wydajności, jeśli aplikacja go nie wymaga. Włącz tę witrynę, wyłącz domyślną, sprawdź konfigurację i przeładuj usługę:
sudo a2ensite testapp
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2Polecenie apache2ctl configtest powinno zwrócić Syntax OK. Linia a2dissite 000-default jest najczęściej pomijaną konfiguracją, co powoduje problem z wyświetlaniem domyślnej strony — szczegóły opisano w sekcji dotyczącej błędów.
Step 6 - Weryfikacja działania PHP, a następnie usunięcie pliku testowego
Utwórz plik PHP zawierający jedną linię w katalogu głównym aplikacji:
echo "<?php phpinfo();" | sudo tee /var/www/testapp/info.phpOtwórz adres http://app.example.com/info.php. Poprawnym wynikiem jest tabela PHP Version 8.3.x w kolorach fioletowym i szarym, zawierająca listę załadowanych modułów, gdzie linia Server API wskazuje FPM/FastCGI. Ta linia potwierdza, że zapytania są obsługiwane przez PHP-FPM, a nie mod_php.
Natychmiast usuń plik:
sudo rm /var/www/testapp/info.phpPlik phpinfo() ujawnia dokładną wersję PHP, wszystkie załadowane rozszerzenia, ścieżki do plików oraz szczegóły środowiska. Stanowi to zagrożenie, jeśli ktoś będzie skanował serwer w poszukiwaniu wersji z podatnością. Jest to jedynie narzędzie testowe. Usuń plik natychmiast po wyświetleniu strony. Jeśli zamiast tabeli przeglądarka zaproponowała pobranie pliku info.php, PHP nie jest poprawnie skonfigurowane do pracy z Apache; przed podjęciem dalszych kroków przejdź do sekcji dotyczącej błędów.
Step 7 - Utworzenie bazy danych aplikacji oraz użytkownika z ograniczonymi uprawnieniami
Należy otworzyć bazę danych jako root z uwierzytelnianiem przez socket:
sudo mysqlNastępnie należy utworzyć jedną bazę danych oraz jednego użytkownika o uprawnieniach ograniczonych wyłącznie do tej bazy:
CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;Zastosowano tutaj trzy celowe rozwiązania. utf8mb4 to rzeczywisty format four-byte UTF-8 — starszy alias utf8 po cichu obcina emoji oraz niektóre znaki CJK, dlatego należy zawsze używać utf8mb4. Uprawnienia (grant) są nadawane dla appdb.*, a nie dla *.*: użytkownik ten ma dostęp tylko do własnej bazy danych, co zapobiega odczytaniu tabel innych witryn w przypadku wystąpienia SQL-injection w aplikacji. Dodatkowo 'appuser'@'localhost' ogranicza konto do połączeń pochodzących wyłącznie z lokalnej maszyny.
Należy przeprowadzić test jako wspomniany użytkownik:
mysql -u appuser -p appdbSystem poprosi o hasło i wyświetli prompt MariaDB [appdb]>. Należy zauważyć brak flagi -h — pozostawienie jej wyłączonej powoduje połączenie przez lokalny Unix socket, co MariaDB uznaje za localhost. Ważna uwaga: dla MySQL oraz MariaDB localhost oznacza Unix socket, natomiast 127.0.0.1 oznacza połączenie TCP. W standardowej instalacji MariaDB na Ubuntu 24.04 serwer nadal mapuje połączenie TCP z 127.0.0.1 na localhost, więc oba typy połączeń pasują do konta. Jednak na serwerach z włączoną funkcją skip-name-resolve (częsta optymalizacja wydajnościowa oraz standard w wielu obrazach kontenerowych), oba typy są traktowane jako różne hosty. W takim przypadku aplikacja próbująca połączyć się przez 127.0.0.1 zostanie odrzucona z błędem ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (using password: YES), nawet jeśli hasło jest poprawne.
Należy skonfigurować aplikację przy użyciu hosta localhost, użytkownika appuser oraz bazy danych appdb — nigdy nie należy używać root. Rozszerzenia PHP mysqli oraz PDO przełączają się na Unix socket, gdy hostem jest dosłowny ciąg znaków localhost, co odpowiada nowo utworzonemu kontu. Jeśli framework wymaga numerycznego hosta TCP, należy utworzyć użytkownika zgodnie z metodą połączenia — 'appuser'@'127.0.0.1', lub @'%' (w połączeniu z regułą firewall) wyłącznie wtedy, gdy dostęp do bazy musi być realizowany z innej maszyny.
Krok 8 - Dodawanie HTTPS za pomocą Certbot
Przesyłanie formularza logowania przez protokół HTTP powoduje przesyłanie haseł w postaci jawnej. Każda nowoczesna przeglądarka oznaczy stronę jako "Not secure". Certbot rozwiązuje ten problem za pomocą jednej komendy. Należy zainstalować narzędzie wraz z wtyczką Apache:
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apacheCertbot wykorzystuje w tym procesie dwa pluginy. apache authenticator potwierdza własność domeny poprzez tymczasowe udostępnienie pliku wyzwania (challenge file) przez działający serwer Apache. Następnie apache installer modyfikuje plik virtual host, dodając blok 443, wskazując nowy certyfikat oraz ustawiając domyślne przekierowanie całego ruchu HTTP na HTTPS. Od wersji Certbot 2.0 pytanie o przekierowanie nie jest wyświetlane; należy przekazać flagę --no-redirect, jeśli wymagane jest dalsze obsługiwanie protokołu HTTP. Ponieważ w Kroku 5 skonfigurowano poprawny ServerName, Certbot automatycznie wykryje domenę. Certyfikaty są ważne przez 90 dni. Pakiet instaluje mechanizm systemd timer, który automatycznie odnawia certyfikaty. Stan timera można zweryfikować za pomocą komendy sudo certbot renew --dry-run, która powinna kończyć się frazą Congratulations, all simulated renewals succeeded.
Pełny opis procesu wyzwania, mechanizmu odnawiania oraz wymagań dotyczących DNS i zapory sieciowej znajduje się w przewodniku wydawaniu bezpłatnych certyfikatów Let's Encrypt TLS za pomocą Certbot na Apache.
Backups, upgrades, and hardening
Należy wykonać kopię zapasową dwóch elementów przechowujących stan systemu: baz danych oraz katalogu root serwera WWW. Najprostszym i niezawodnym podejściem jest codzienne wykonywanie logicznego zrzutu danych — sudo sh -c 'mysqldump --all-databases --single-transaction | gzip > /root/db-$(date +%F).sql.gz', a następnie kopiowanie go poza serwer. Kluczowe jest objęcie całego procesu narzędziem sudo sh -c: bez niego powłoka shell wykonuje przekierowanie > /root/... z uprawnieniami bieżącego użytkownika, co skutkuje błędem Permission denied, ponieważ tylko mysqldump posiada dziedziczenie sudo. --single-transaction tworzy spójny obraz tabel InnoDB bez ich blokowania. Łącząc to z tar plików /var/www oraz /etc/apache2/sites-available, można odtworzyć cały stos technologiczny na nowym VPS z tych plików.
Aktualizacje są standardowym procesem sudo apt update && sudo apt upgrade. Największym problemem jest zmiana wersji PHP — gdy przyszła wersja Ubuntu zmieni domyślną wersję na PHP 8.4, apt może zainstalować php8.4-fpm obok wersji 8.3, gniazdo (socket) zmieni się na /run/php/php8.4-fpm.sock, a konfiguracja Apache nadal będzie wskazywać gniazdo wersji 8.3. Należy aktywować nową konfigurację (sudo a2enconf php8.4-fpm) i wyłączyć starą, w przeciwnym razie strona zacznie zwracać błąd Primary script unknown po rutynowej aktualizacji. Ponieważ wersje PHP pojawiają się szybciej niż dystrybucje LTS, należy sprawdzać aktualne instrukcje wydawnicze PHP, zamiast blokować konkretną wersję patch.
Warto wdrożyć dwa kroki wzmacniające bezpieczeństwo (hardening) pierwszego dnia. Po pierwsze, należy zainstalować Fail2Ban monitorujący SSH — publiczny VPS otrzymuje automatyczne próby logowania w ciągu kilku minut, a małe więzienie (jail) zamienia tysiące prób w kilka zdarzeń przed nałożeniem blokady. Po drugie, jeśli zamiast ręcznej edycji plików wolisz zarządzać wirtualnymi hostami Apache, bazami danych MariaDB i użytkownikami przez przeglądarkę, panel sterowania Webmin działa na tym samym stosie technologicznym i zarządza tymi samymi plikami konfiguracyjnymi. Żadne z tych narzędzi nie zastępuje wiedzy o poszczególnych komponentach, ale oba redukują codzienne trudności w zarządzaniu.
Tryby awarii i wyświetlane komunikaty
Strona domyślna nie znika. Po edycji virtual host i przeładowaniu usługi przeglądarka nadal wyświetla "Apache2 Ubuntu Default Page" oraz baner "It works!". Apache serwuje pierwszy pasujący virtual host. Jeśli żaden ServerName nie pasuje do zapytania, wygrywa pierwsza konfiguracja w porządku alfabetycznym — 000-default.conf znajduje się przed testapp.conf. Nazwa hosta w zapytaniu nie zgadza się z ServerName lub nie wykonano polecenia sudo a2dissite 000-default. Należy wyłączyć stronę domyślną, sudo systemctl reload apache2, i potwierdzić wynik poleceniem apache2ctl -S, które wypisuje mapę vhost i pokazuje, która konfiguracja obsługuje stronę domyślną. Należy również wyczyścić pamięć podręczną przeglądarki; zakodowany status 200 ze starej strony może być nadal wyświetlany.
Plik .php zamiast uruchomienia jest pobierany. Po otwarciu info.php przeglądarka pobiera plik z surowym kodem źródłowym <?php lub wyświetla go jako tekst zamiast go uruchomić. Apache serwuje plik jako zasób statyczny, ponieważ handler PHP nie został przypisany — pominięto sudo a2enmod proxy_fcgi, sudo a2enconf php8.3-fpm lub nie zrestartowano usługi Apache. Należy wykonać wszystkie trzy kroki (Step 4) i przeładować usługę. Sprawdzenie załadowania modułu wykonuje się poleceniem apache2ctl -M | grep fcgi, które powinno wymienić proxy_fcgi_module. Jest to wyciek kodu źródłowego, a nie błąd kosmetyczny, dlatego należy to naprawić przed umieszczeniem rzeczywistych danych na serwerze.
ERROR 1698 (28000): Access denied for user 'root'@'localhost'. Polecenie mysql -u root lub mariadb -u root wykonano bez sudo. Konto root używa uwierzytelniania unix_socket, więc akceptuje połączenie tylko wtedy, gdy użytkownik systemu operacyjnego to root. Rozwiązaniem jest sudo mysql — brak -u root i brak hasła. Komunikat ten jest prawidłowym zachowaniem przy działającym uwierzytelnianiu socket, a nie błędem instalacji.
ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' z aplikacji przy użyciu poprawnego hasła. Konto istnieje jako 'appuser'@'localhost', ale aplikacja łączy się przez TCP do 127.0.0.1 na serwerze, gdzie rozwiązanie nazw hostów jest wyłączone (skip-name-resolve). MariaDB uznaje oba połączenia za różne hosty — localhost to Unix socket, 127.0.0.1 to TCP. Należy skierować aplikację na host localhost, aby używała socketu i pasowała do konta, lub utworzyć drugie konto 'appuser'@'127.0.0.1', jeśli framework obsługuje wyłącznie TCP.
AH01071: Got error 'Primary script unknown' w /var/log/apache2/testapp-error.log, gdy przeglądarka wyświetla File not found.. Apache przekazał zapytanie do PHP-FPM, ale FPM nie znalazł skryptu w ścieżce podanej przez Apache. Dwie typowe przyczyny: socket FPM w konfiguracji wskazuje na wersję PHP, która nie jest zainstalowana (socket php8.4 po aktualizacji, gdy działa tylko 8.3), lub plik fizycznie nie istnieje, ponieważ DocumentRoot i rzeczywisty katalog są niezgodne. Należy sprawdzić istnienie socketu za pomocą ls -l /run/php/, potwierdzić, czy DocumentRoot zgadza się z lokalizacją pliku, oraz zrestartować php8.3-fpm i apache2.
AH00558: apache2: Could not reliably determine the server's fully qualified domain name przy każdym restarcie. Jest to ostrzeżenie, a nie błąd — Apache informuje, że nie ustawiono globalnego ServerName. Można je wyciszyć, wpisując ServerName your.domain do /etc/apache2/conf-available/servername.conf i uruchamiając sudo a2enconf servername.
(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80 podczas uruchamiania Apache. Inny serwer WWW zajmuje port 80 — często jest to proces nginx pozostały po poprzednich testach. Należy go odnaleźć za pomocą sudo ss -ltnp | grep :80, a następnie zatrzymać i wyłączyć tę usługę przed uruchomieniem Apache.
FAQ
mod_php czy PHP-FPM - czego należy używać?
Należy używać PHP-FPM. mod_php osadza interpreter w każdym procesie Apache i wymusza powolny prefork MPM, przez co Apache obciąża zasoby PHP nawet podczas serwowania statycznych obrazów. PHP-FPM uruchamia PHP jako oddzielny, niezależnie optymalizowany pool, do którego Apache łączy się przez socket. Pozwala to na pracę z szybszym, wątkowym event MPM i ułatwia późniejszą migrację do nginx. Jest to nowoczesny standard; mod_php ma sens tylko w przypadku starszych aplikacji wymagających zachowań wewnątrz procesu.
Dlaczego przeglądarka pobiera plik PHP zamiast go uruchomić?
Apache traktuje plik .php jako statyczny plik do pobrania, ponieważ nie przypisano do niego obsługi PHP (PHP handler). W systemie Ubuntu 24.04 z FPM oznacza to pominięcie jednego z kroków: sudo a2enmod proxy_fcgi, sudo a2enconf php8.3-fpm lub restartu usługi Apache. Należy wykonać wszystkie trzy kroki i przeładować usługę, a następnie sprawdzić za pomocą apache2ctl -M | grep fcgi, czy proxy_fcgi_module znajduje się na liście. Do czasu naprawy błędu serwer udostępnia kod źródłowy, co wymaga pilnej interwencji.
Dlaczego dostęp root w MariaDB jest odmawiany mimo poprawnego hasła?
Dostęp jest odmawiany, ponieważ hasło nie jest wymagane — MariaDB w systemie Ubuntu uwierzytelnia konto root za pomocą unix_socket, wiążąc je z użytkownikiem root systemu operacyjnego. Polecenie mysql -u root uruchomione z poziomu zwykłej powłoki zwraca ERROR 1698 (28000): Access denied for user 'root'@'localhost' zgodnie z projektem. Należy użyć sudo mysql i utworzyć oddzielnego użytkownika z uwierzytelnianiem hasłem dla każdej aplikacji, zamiast używać konta root.
Jak dodać HTTPS do witryny LAMP?
Należy zainstalować certbot oraz python3-certbot-apache, skierować rekord A domeny na serwer, a następnie uruchomić sudo certbot --apache. Mechanizm uwierzytelniania Apache potwierdza kontrolę nad domeną poprzez działającą usługę Apache, a instalator modyfikuje wirtualny host dla portu 443 i konfiguruje automatyczne odnawianie. Pełny przewodnik po Certbot i Apache opisuje proces weryfikacji, harmonogram odnawiania oraz typowe błędy.