LAMP na Ubuntu 24.04: PHP-FPM i Apache
Instrukcja konfiguracji Apache, MariaDB z unix_socket, PHP 8.3 z PHP-FPM, vhosta name-based oraz bezpłatnego HTTPS Let's Encrypt na Ubuntu 24.04.
Co jest budowane
Stos LAMP składa się z czterech elementów działających na jednym serwerze Ubuntu 24.04: systemu Linux, usługi Apache obsługującej protokół HTTP, bazy danych MariaDB oraz środowiska PHP 8.3 wykonującego kod. Po zakończeniu konfiguracji będzie działać wirtualny host oparty na nazwie, obsługujący rzeczywisty katalog aplikacji, baza danych z dedykowanym użytkownikiem o minimalnych uprawnieniach, PHP połączone z Apache za pośrednictwem PHP-FPM oraz bezpłatny certyfikat Let's Encrypt.
Sama instalacja obejmuje cztery polecenia apt. Większość tego poradnika opisuje połączenie tych elementów oraz niewielki zestaw błędów, które powodują, że nowo utworzony stos wyświetla pustą stronę, przekazuje kod źródłowy do przeglądarki jako plik do pobrania albo odmawia dostępu do dopiero zainstalowanej bazy danych. Każdy z tych problemów ma rozpoznawalny charakterystyczny objaw. Poniżej podano jego nazwę oraz dokładny tekst wyświetlany w danej sytuacji.
Wymagania wstępne i istotne uwagi
Należy założyć użycie nowego VPS KVM z Ubuntu 24.04, użytkownikiem z uprawnieniami sudo lub kontem root oraz publicznym adresem IPv4. Minimalny stos działa przy 1 GB pamięci RAM. Przed wdrożeniem rzeczywistej aplikacji korzystającej z bazy danych należy zwiększyć pamięć do 2 GB, ponieważ domyślne bufory MariaDB oraz kilka procesów roboczych PHP-FPM szybko zużywają pierwszy gigabajt.
Przed uruchomieniem Certbot na końcu muszą być spełnione 2 warunki, dlatego należy przygotować je teraz. Wymagana jest nazwa domeny z rekordem A wskazującym publiczny adres IP VPS. Let's Encrypt przeprowadza walidację przez HTTP dla tej nazwy, a dla samego adresu IP nie można uzyskać certyfikatu. Porty 80 i 443 muszą być dostępne z internetu. U wielu dostawców oznacza to konieczność otwarcia ich w zaporze sieciowej w panelu sterowania oraz w ufw na serwerze. Zmiany DNS mogą propagować się do 1 godziny, dlatego rekord A należy skonfigurować z wyprzedzeniem. Będzie aktywny, gdy stanie się potrzebny.
Krok 1 - Zainstalowanie Apache i sprawdzenie strony domyślnej
sudo apt update
sudo apt install -y apache2apt uruchamia usługę i włącza jej automatyczne uruchamianie. Sprawdź jej stan:
systemctl status apache2Powinien pojawić się wiersz zawierający active (running). Otwórz teraz http://YOUR_SERVER_IP/ w przeglądarce. Prawidłowym wynikiem jest strona Apache2 Ubuntu Default Page z dużym banerem „It works!”. Potwierdza ona, że Apache udostępnia zawartość, a nie sygnalizuje błędu. Strona znajduje się w /var/www/html/index.html i jest udostępniana przez dostarczony domyślny wirtualny host 000-default.conf. Oba elementy zostaną później wyłączone. Na tym etapie ich obecność jest dokładnie tym, co powinno być widoczne.
Jeśli strona w ogóle się nie ładuje, ale systemctl wskazuje, że proces działa, przyczyną jest zapora sieciowa. To będzie następny krok.
Krok 2 — Otwieranie zapory dla HTTP i HTTPS
Pakiet apache2 rejestruje trzy profile aplikacji ufw. Należy je wyświetlić:
sudo ufw app listZostaną wyświetlone Apache, Apache Full oraz Apache Secure. Apache obejmuje tylko port 80, Apache Secure tylko port 443, a Apache Full obejmuje oba porty. Należy wybrać Apache Full, ponieważ TLS zostanie skonfigurowany na końcu.
sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
sudo ufw enableNależy zezwolić na OpenSSH przed uruchomieniem ufw enable. Domyślnie ufw odrzuca cały ruch przychodzący. Włączenie go bez reguły SSH odcina własne połączenie w chwili aktywacji. Bieżąca sesja pozostaje aktywna, ale nie można już nawiązać ponownego połączenia. Należy potwierdzić ustawienia za pomocą sudo ufw status. Wartości dla OpenSSH, Apache Full oraz ich odpowiedników v6 powinny wynosić ALLOW.
Krok 3 - Instalacja MariaDB i zabezpieczenie
sudo apt install -y mariadb-server
systemctl status mariadbUbuntu 24.04 dostarcza MariaDB 10.11, czyli wydanie z długoterminowym okresem wsparcia, dlatego nie jest potrzebne zewnętrzne repozytorium. Po uruchomieniu usługi należy ją zabezpieczyć:
sudo mysql_secure_installationWarto przeczytać wyświetlane pytania, zamiast bezmyślnie naciskać Enter. Po wyświetleniu pytania o bieżące hasło root należy nacisnąć Enter, ponieważ nie zostało ono jeszcze ustawione. W przypadku pytania „Switch to unix_socket authentication?” odpowiedź niczego nie zmienia, ponieważ uwierzytelnianie jest już włączone w tym pakiecie, dlatego należy nacisnąć n. Na pytanie „Change the root password?” należy odpowiedzieć n z powodu opisanego w następnym akapicie, a na pozostałe pytania odpowiedzieć Y: usunąć użytkowników anonimowych, zabronić zdalnego logowania użytkownika root, usunąć testową bazę danych i ponownie wczytać tabele uprawnień.
Poniższa kwestia często powoduje nieporozumienia. W MariaDB na Ubuntu konto bazy danych root korzysta z uwierzytelniania unix_socket, a nie z hasła. Oznacza to, że baza ufa użytkownikowi systemu operacyjnego, który został już uwierzytelniony. Dlatego z powłoki root działa następujące polecenie:
sudo mysql...i wyświetla monit MariaDB [(none)]> bez żądania hasła. To samo polecenie uruchomione przez użytkownika bez uprawnień zostaje odrzucone, co jest głównym celem tego rozwiązania: dostęp do użytkownika root bazy danych jest powiązany z użytkownikiem sudo na serwerze, a hasła nie można wykraść, wyłudzić ani odgadnąć metodą brute-force. Jest to bezpieczniejsze niż użycie hasła, dlatego należy pozostawić tę konfigurację bez zmian. Wynika z tego następująca zasada: nigdy nie należy konfigurować aplikacji z użyciem konta root. Należy utworzyć osobnego użytkownika dla każdej aplikacji (Krok 7), ponieważ aplikacja łącząca się przez TCP za pomocą nazwy użytkownika i hasła nie może korzystać z uwierzytelniania przez gniazdo, a każda aplikacja powinna mieć dostęp wyłącznie do własnej bazy danych.
Krok 4 — Instalacja PHP 8.3 z PHP-FPM
Domyślna wersja PHP w Ubuntu 24.04 to 8.3. Należy zainstalować menedżer procesów FPM oraz rozszerzenia wymagane przez typową aplikację:
sudo apt install -y php8.3-fpm php8.3-mysql php8.3-cli \
php8.3-curl php8.3-xml php8.3-mbstring php8.3-zipNa tej liście nie ma libapache2-mod-php. Ten starszy pakiet osadza interpreter PHP w każdym procesie Apache. Jest prosty, ale każdy proces roboczy zawiera kopię PHP, niezależnie od tego, czy obsługuje skrypt, czy obraz statyczny. Oba komponenty mają wspólny cykl życia. Rozwiązanie działa tylko z modułem MPM prefork Apache, który jest najmniej wydajny. PHP-FPM uruchamia PHP we własnej puli procesów, z którą Apache komunikuje się przez gniazdo. Apache może wtedy używać wielowątkowego modułu MPM event do obsługi plików statycznych i przekazywać do puli tylko żądania PHP. Pulę można konfigurować niezależnie od serwera WWW. Dokładnie ta sama konfiguracja FPM będzie działać później, jeśli przed Apache zostanie użyty nginx. Jest to obecnie rozwiązanie domyślne z uzasadnionych powodów.
Apache uzyskuje dostęp do FPM za pośrednictwem modułu proxy_fcgi. Należy go włączyć, włączyć konfigurację zainstalowaną przez pakiet FPM i ponownie uruchomić 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. Plik ten zawiera regułę przekazującą pliki PHP do gniazda FPM. Reguła dopasowuje dowolny plik .php i przekazuje go do gniazda 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>Nie należy edytować tego pliku. Jest dostarczany z poprawną zawartością. Znajomość ścieżki gniazda ułatwia jednak diagnozowanie późniejszych błędów „PHP jest pobierane zamiast wykonywane” oraz „Primary script unknown”. Oba błędy wynikają z rozbieżności między Apache i FPM dotyczącej tego gniazda lub pliku znajdującego się za nim.
Krok 5 - Wirtualny host oparty na nazwie dla aplikacji
Wirtualne hostowanie oparte na nazwie pozwala obsługiwać wiele witryn z jednego adresu IP. Apache wybiera witrynę na podstawie nagłówka Host: w żądaniu. Należy utworzyć katalog aplikacji z dala od domyślnego katalogu /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łaściciel ma znaczenie. Apache i PHP-FPM działają w systemie Ubuntu jako użytkownik www-data. Dlatego pliki, które serwer WWW musi odczytywać, oraz katalogi, do których aplikacja musi zapisywać dane, na przykład katalog uploads, powinny należeć do www-data. Jeśli pliki będą również edytowane jako zalogowany użytkownik, często stosuje się rozwiązanie polegające na przypisaniu plików do własności tego użytkownika i dodaniu go do grupy www-data. W przypadku zwykłego wdrożenia najmniej zaskakującym wyborem jest www-data:www-data.
Należy utworzyć wirtualny 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>Należy ustawić ServerName na właściwą domenę. Options -Indexes uniemożliwia Apache wyświetlanie zawartości katalogu, gdy nie ma pliku indeksu. W przeciwnym razie odwiedzający mogą przeglądać drzewo kodu źródłowego. AllowOverride All umożliwia działanie pliku .htaccess, czego oczekuje większość aplikacji PHP w przypadku przyjaznych adresów URL. Jeśli aplikacja go nie wymaga, można zmienić tę wartość na None, aby uzyskać niewielki wzrost wydajności. Należy włączyć tę witrynę, wyłączyć domyślną, sprawdzić konfigurację i ponownie wczytać konfigurację:
sudo a2ensite testapp
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2Polecenie apache2ctl configtest powinno wyświetlić Syntax OK. Wiersz a2dissite 000-default jest często pomijany. Z tego powodu domyślna strona może później nadal się wyświetlać, co opisano w sekcji dotyczącej błędów.
Krok 6 - Sprawdzenie działania PHP, a następnie usunięcie pliku testowego
Umieść jednolinijkowy plik PHP w katalogu głównym aplikacji:
echo "<?php phpinfo();" | sudo tee /var/www/testapp/info.phpOtwórz adres http://app.example.com/info.php. Prawidłowy wynik to długa, fioletowo-szara tabela PHP Version 8.3.x zawierająca listę załadowanych modułów. Wiersz Server API powinien zawierać wartość FPM/FastCGI. Potwierdza to, że żądania są obsługiwane przez PHP-FPM, a nie przez mod_php.
Następnie natychmiast usuń ten plik:
sudo rm /var/www/testapp/info.phpphpinfo() ujawnia dokładną wersję PHP, wszystkie załadowane rozszerzenia, ścieżki do plików oraz szczegóły środowiska. Stanowi to cenną informację dla osób skanujących serwer w poszukiwaniu wersji ze znaną luką. Jest to test, a nie funkcja aplikacji. Należy usunąć ten plik natychmiast po wyświetleniu strony. Jeżeli przeglądarka zamiast tabeli proponuje pobranie pliku info.php, PHP nie jest skonfigurowane do współpracy z Apache. Przed wykonaniem jakichkolwiek innych czynności należy przejść do sekcji dotyczącej błędów.
Krok 7 - Utworzenie bazy danych aplikacji i użytkownika z minimalnymi uprawnieniami
Otwórz bazę danych jako uwierzytelniony za pomocą gniazda użytkownik root:
sudo mysqlNastępnie utwórz jedną bazę danych i jednego użytkownika ograniczonego 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;W tym miejscu celowo zastosowano trzy rozwiązania. utf8mb4 oznacza rzeczywiste czterobajtowe kodowanie UTF-8. Stary alias utf8 po cichu obcina znaki emoji i niektóre znaki CJK, dlatego należy zawsze używać utf8mb4. Nadanie uprawnień dotyczy appdb.*, a nie *.*. Ten użytkownik może uzyskiwać dostęp tylko do własnej bazy danych, więc luka typu SQL injection w aplikacji nie pozwoli mu odczytać tabel wszystkich pozostałych witryn. Natomiast 'appuser'@'localhost' ogranicza konto do połączeń nawiązywanych lokalnie na tym samym serwerze.
Przetestuj połączenie jako ten użytkownik:
mysql -u appuser -p appdbZostanie wyświetlona prośba o hasło, a następnie pojawi się znak zachęty MariaDB [appdb]>. Należy zauważyć brak flagi -h. Powinna pozostać pominięta, aby klient połączył się za pośrednictwem lokalnego gniazda Unix, które MariaDB traktuje dokładnie jako localhost. Należy znać jedną istotną różnicę: dla MySQL i MariaDB localhost oznacza gniazdo Unix, a 127.0.0.1 oznacza połączenie TCP. W standardowej instalacji MariaDB w Ubuntu 24.04 serwer nadal mapuje połączenie TCP z 127.0.0.1 na localhost, dlatego oba połączenia pasują do tego konta. Jednak na serwerach z włączonym skip-name-resolve, co jest częstą optymalizacją wydajności i standardem w wielu obrazach kontenerów, oba połączenia są dopasowywane jako pochodzące od różnych hostów. W takiej sytuacji aplikacja łącząca się przez 127.0.0.1 otrzyma odmowę z komunikatem ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (using password: YES) nawet przy prawidłowym haśle.
Skonfiguruj więc aplikację z hostem localhost, użytkownikiem appuser i bazą danych appdb, nigdy zaś z root. PHP mysqli oraz PDO przełączają się na lokalne gniazdo Unix, gdy host jest dosłownym ciągiem localhost, co odpowiada utworzonemu przed chwilą kontu. Jeśli framework wymaga numerycznego hosta TCP, utwórz użytkownika odpowiadającego faktycznemu sposobowi nawiązywania połączenia: 'appuser'@'127.0.0.1' lub @'%' (w połączeniu z regułą zapory), ale tylko wtedy, gdy baza danych musi być dostępna z innego komputera.
Krok 8 - Dodawanie HTTPS za pomocą Certbot
Przesyłanie formularza logowania przez zwykły HTTP powoduje wysyłanie haseł otwartym tekstem, a każda nowoczesna przeglądarka oznacza taką stronę jako "Niebezpieczną". Certbot rozwiązuje ten problem za pomocą jednego polecenia. Należy zainstalować go wraz z wtyczką dla Apache:
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apacheCertbot wykorzystuje tutaj dwie wtyczki. Authenticator apache potwierdza kontrolę nad domeną poprzez krótkotrwałe udostępnienie pliku weryfikacyjnego przez działający serwer Apache, a installer apache modyfikuje plik wirtualnego hosta, dodając blok 443, wskazując na nowy certyfikat i domyślnie przekierowując cały ruch HTTP na HTTPS. Certbot nie pyta o przekierowanie od wersji 1.4.0 (maj 2020), więc należy przekazać flagę --no-redirect, jeśli konieczne jest utrzymanie obsługi zwykłego HTTP. Ponieważ w kroku 5 ustawiono poprawny ServerName, Certbot automatycznie wykrywa domenę. Certyfikaty wydawane obecnie są ważne przez 90 dni (Let's Encrypt skraca domyślny okres ważności do 64 dni w dniu 10 lutego 2027 oraz do 45 dni w dniu 16 lutego 2028), a pakiet instaluje timer systemd, który automatycznie je odnawia; poprawność timera można zweryfikować za pomocą sudo certbot renew --dry-run, co powinno zakończyć się komunikatem Congratulations, all simulated renewals succeeded.
Pełny opis procesu weryfikacji, timera odnawiania oraz wymagań dotyczących DNS i zapory sieciowej znajduje się w przewodniku wydawanie darmowych certyfikatów TLS Let's Encrypt za pomocą Certbot na Apache.
Kopie zapasowe, aktualizacje i zabezpieczanie systemu
Należy tworzyć kopie zapasowe dwóch elementów przechowujących stan: baz danych oraz katalogu głównego serwera WWW. Najprostszym niezawodnym rozwiązaniem jest nocny zrzut logiczny, sudo sh -c 'mysqldump --all-databases --single-transaction | gzip > /root/db-$(date +%F).sql.gz', a następnie skopiowanie go poza serwer. Kluczowe jest opakowanie całego procesu w sudo sh -c: bez tego powłoka wykona przekierowanie > /root/... z uprawnieniami bieżącego użytkownika, co zakończy się błędem Permission denied, ponieważ tylko mysqldump odziedziczył sudo. --single-transaction zapewnia spójną migawkę tabel InnoDB bez ich blokowania. W połączeniu z tar katalogów /var/www oraz /etc/apache2/sites-available, możliwe jest odtworzenie całego stosu na nowym serwerze VPS przy użyciu tych plików.
Aktualizacje to standardowe sudo apt update && sudo apt upgrade. Problematyczna bywa zmiana wersji PHP podczas aktualizacji wydania systemu. Ubuntu 26.04 LTS dostarcza PHP 8.5 jako wersję domyślną, a pakiety php8.3-* zainstalowane w tym przewodniku nie istnieją w tej wersji. Po aktualizacji uruchomiona zostanie wersja php8.5-fpm, gniazdo zmieni się na /run/php/php8.5-fpm.sock, a konfiguracja Apache nadal będzie wskazywać na gniazdo 8.3. Należy włączyć nową konfigurację (sudo a2enconf php8.5-fpm) i wyłączyć starą, w przeciwnym razie po rutynowej aktualizacji witryna zacznie zwracać błąd Primary script unknown. Ponieważ wydania PHP pojawiają się częściej niż wersje LTS dystrybucji, należy sprawdzać bieżące informacje o wydaniu PHP zamiast przypisywać konkretną wersję poprawki.
Warto wykonać dwa kroki zabezpieczające już pierwszego dnia. Po pierwsze, należy zainstalować Fail2Ban monitorujący SSH; publiczny serwer VPS otrzymuje zautomatyzowane próby logowania w ciągu kilku minut, a odpowiednia reguła ograniczy tysiące prób do kilku przed nałożeniem blokady. Po drugie, jeśli zarządzanie wirtualnymi hostami Apache, bazami danych MariaDB i użytkownikami ma odbywać się przez przeglądarkę, a nie poprzez ręczną edycję plików, panel sterowania Webmin współpracuje z tym samym stosem i zarządza tymi samymi plikami konfiguracyjnymi, które zostały właśnie utworzone. Żadne z tych narzędzi nie zastępuje zrozumienia działania poszczególnych komponentów, ale oba redukują codzienny nakład pracy.
Tryby awarii i towarzyszące im komunikaty
Domyślna strona nie znika. Po edycji wirtualnego hosta i przeładowaniu konfiguracji przeglądarka nadal wyświetla stronę "Apache2 Ubuntu Default Page" z nagłówkiem "It works!". Apache obsługuje pierwszego pasującego wirtualnego hosta. Gdy żadne ServerName nie pasuje do żądania, wygrywa konfiguracja pierwsza w porządku alfabetycznym, ponieważ 000-default.conf sortuje się przed testapp.conf. Przyczyną jest brak dopasowania nazwy hosta w żądaniu do Twojego ServerName lub pominięcie polecenia sudo a2dissite 000-default. Wyłącz domyślną konfigurację, wykonaj sudo systemctl reload apache2, a następnie potwierdź stan poleceniem apache2ctl -S, które wyświetla mapę vhostów i wskazuje, która konfiguracja obsługuje domyślny adres. Wyczyść również pamięć podręczną przeglądarki; zapisany w niej kod 200 dla starej strony może nadal powodować jej wyświetlanie.
Plik .php pobiera się zamiast uruchamiać. Po otwarciu info.php przeglądarka pobiera plik zawierający surowy kod źródłowy <?php lub wyświetla go jako zwykły tekst zamiast wykonać skrypt. Apache traktuje plik jako zasób statyczny, ponieważ procedura obsługi PHP nie została podpięta, pominięto sudo a2enmod proxy_fcgi lub sudo a2enconf php8.3-fpm, albo nie zrestartowano serwera Apache po zmianach. Wykonaj wszystkie trzy kroki (Krok 4) i przeładuj usługę. Potwierdź załadowanie modułu za pomocą apache2ctl -M | grep fcgi, co powinno wyświetlić proxy_fcgi_module. Jest to wyciek kodu źródłowego, a nie błąd kosmetyczny, dlatego należy go naprawić przed umieszczeniem na serwerze jakichkolwiek rzeczywistych danych.
ERROR 1698 (28000): Access denied for user 'root'@'localhost'. Uruchomiono mysql -u root lub mariadb -u root bez sudo. Konto root używa uwierzytelniania unix_socket, więc akceptuje połączenie tylko wtedy, gdy użytkownik systemu operacyjnego to rzeczywiście root. Rozwiązaniem jest sudo mysql, bez -u root i bez hasła. Ten komunikat jest oczekiwanym zachowaniem poprawnie działającego uwierzytelniania przez gniazdo, a nie objawem uszkodzonej instalacji.
ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' z poziomu aplikacji, mimo poprawnego hasła. Konto istnieje jako 'appuser'@'localhost', ale aplikacja łączy się przez TCP z 127.0.0.1 na serwerze, gdzie rozwiązywanie nazw hostów jest wyłączone (skip-name-resolve). W rezultacie MariaDB traktuje te dwa połączenia jako pochodzące od różnych hostów: localhost to gniazdo Unix, a 127.0.0.1 to TCP. Skieruj aplikację na host localhost, aby używała gniazda i dopasowała konto, lub utwórz drugie konto 'appuser'@'127.0.0.1', jeśli framework obsługuje wyłącznie protokół TCP.
AH01071: Got error 'Primary script unknown' w /var/log/apache2/testapp-error.log, przy czym przeglądarka wyświetla File not found.. Apache przekazał żądanie do PHP-FPM, ale FPM nie mógł odnaleźć skryptu pod ścieżką wskazaną przez Apache. Istnieją dwie typowe przyczyny: gniazdo FPM w konfiguracji wskazuje na wersję PHP, która nie jest zainstalowana (gniazdo 8.3 pozostało skonfigurowane po aktualizacji wydania do PHP 8.5), lub plik fizycznie nie znajduje się w danej lokalizacji, ponieważ DocumentRoot i rzeczywisty katalog są ze sobą sprzeczne. Sprawdź, czy gniazdo istnieje za pomocą ls -l /run/php/, potwierdź, że DocumentRoot odpowiada lokalizacji pliku, a następnie zrestartuj zarówno php8.3-fpm (lub inną zainstalowaną wersję PHP-FPM), jak i apache2.
AH00558: apache2: Could not reliably determine the server's fully qualified domain name przy każdym restarcie. Jest to niegroźne 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 wykonują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 już port 80, często jest to nginx pozostały po poprzednich testach. Znajdź go za pomocą sudo ss -ltnp | grep :80, a następnie zatrzymaj i wyłącz tę usługę przed uruchomieniem Apache.
FAQ
mod_php czy PHP-FPM — którego rozwiązania użyć?
Należy użyć PHP-FPM. mod_php osadza interpreter w każdym procesie Apache i wymusza użycie wolnego MPM prefork, dlatego Apache zużywa zasoby PHP nawet podczas serwowania statycznego obrazu. PHP-FPM uruchamia PHP jako oddzielną pulę, którą można niezależnie dostroić. Apache łączy się z nią przez gniazdo. Rozwiązanie działa z szybszym, wielowątkowym MPM event i można je później bez zmian przenieść do nginx. Jest to obecnie standardowa konfiguracja. mod_php ma sens wyłącznie w przypadku starszej aplikacji zależnej od określonego działania wewnątrz procesu.
Dlaczego przeglądarka pobiera plik PHP zamiast go wykonywać?
Apache traktuje plik .php jako statyczny plik do pobrania, ponieważ nie przypisano do niego obsługi PHP. W Ubuntu 24.04 z FPM oznacza to pominięcie jednego z elementów: sudo a2enmod proxy_fcgi, sudo a2enconf php8.3-fpm albo ponownego uruchomienia Apache. Należy wykonać wszystkie trzy czynności i ponownie wczytać konfigurację, a następnie za pomocą apache2ctl -M | grep fcgi sprawdzić, czy wymieniono proxy_fcgi_module. Do czasu usunięcia problemu serwer ujawnia kod źródłowy, dlatego należy potraktować go jako pilny.
Dlaczego dostęp do root w MariaDB jest odrzucany mimo podania prawidłowego hasła?
Ponieważ konto root nie ma hasła, MariaDB w Ubuntu uwierzytelnia konto root za pomocą unix_socket, wiążąc je z użytkownikiem root systemu operacyjnego. Polecenie mysql -u root wykonane z powłoki zwykłego użytkownika zwraca ERROR 1698 (28000): Access denied for user 'root'@'localhost' zgodnie z założeniami konfiguracji. Należy użyć sudo mysql, a dla każdej aplikacji utworzyć oddzielne konto uwierzytelniane hasłem zamiast ponownie używać konta root.
Jak dodać HTTPS do witryny LAMP?
Należy zainstalować certbot i python3-certbot-apache, skierować rekord A domeny na serwer, a następnie uruchomić sudo certbot --apache. Moduł uwierzytelniający apache potwierdza kontrolę nad domeną za pośrednictwem działającego Apache. Instalator modyfikuje konfigurację wirtualnego hosta dla portu 443 i konfiguruje automatyczne odnawianie certyfikatu. Pełny przewodnik po Certbot i Apache opisuje proces weryfikacji, licznik czasu odnawiania oraz typowe przyczyny niepowodzeń.