Przejdź do treści
Lekcja 88 z 117

Kurs › Moduł 10 › Lekcja 88

Apache: instalacja

⏱ ok. 10 min czytania· moduł 10: Usługi i serwery

Po tej lekcji: kursant instaluje Apache na Ubuntu i RHEL, uruchamia go na stałe, otwiera port 80 w zaporze, wrzuca pierwszą stronę i umie sprawdzić, czy serwer naprawdę odpowiada.

Wstęp

przeglądarka, w pasku adres http://192.168.1.50, a na stronie wielki napis „Witaj na moim serwerze!”

Do tej pory wszystko, co robiliśmy, widziałeś tylko Ty, w czarnym okienku. Dziś pierwszy raz zrobisz coś, co może zobaczyć każdy. Wpisujesz adres serwera w przeglądarce na telefonie, a tam Twoja strona. Twoja. Na Twoim serwerze. Nie na żadnym kreatorze stron za 9,99 miesięcznie.

To jest moment, w którym ludzie zaczynają mówić „mam serwer” takim tonem, jakby mówili „mam jacht”.

Serwer WWW, czyli recepcja hotelu

Wyobraź sobie hotel. Gość podchodzi do recepcji i mówi: „Poproszę pokój 204”. Recepcjonista sprawdza, czy pokój istnieje, czy gość ma do niego prawo, i albo daje klucz, albo mówi „nie ma takiego pokoju”.

Serwer WWW to taka recepcja. Przeglądarka podchodzi i mówi: „Poproszę /index.html”. Serwer szuka pliku i odpowiada kodem: 200 „proszę, oto pokój”, 404 „nie ma takiego pokoju”, 403 „pokój jest, ale nie dla pana”, 500 „recepcjonista zemdlał”. Język tej rozmowy to HTTP. A recepcja stoi przy okienku numer 80, bo pamiętasz, port to numer okienka w urzędzie.

Apache HTTP Server, w skrócie Apache, to jeden z najstarszych i najpopularniejszych recepcjonistów w internecie. Drugim jest Nginx, poznasz go za trzy lekcje.

Instalacja

I tu pierwsza różnica między rodzinami. Ten sam program, dwie nazwy.

sudo apt update
sudo apt install apache2
sudo dnf install httpd

Na Ubuntu pakiet i usługa nazywają się apache2. Na RHEL httpd, od „HTTP daemon”. To ten sam Apache, tylko inaczej podpisany. Jak ten sam serek w dwóch sklepach pod dwiema markami.

Wersję sprawdzisz tak:

apache2 -v      # Ubuntu
httpd -v        # RHEL
Server version: Apache/2.4.58 (Ubuntu)

Uruchomienie na stałe

Na Ubuntu Apache startuje sam od razu po instalacji. Na RHEL nie, tam usługi po instalacji grzecznie czekają, aż admin je włączy. Zawsze lepiej to zrobić jawnie:

sudo systemctl enable --now apache2    # Ubuntu
sudo systemctl enable --now httpd      # RHEL
systemctl status apache2

enable to „uruchamiaj przy każdym starcie systemu”, --now to „i odpal teraz”. Bez enable serwer działa do pierwszego restartu, a potem klient dzwoni w poniedziałek rano, że strona leży. Bez --now serwer będzie działał, ale dopiero od następnego restartu. Dwie połówki jednej czynności, a na egzaminie RHCSA brak enable to klasyczny sposób na stracenie punktów.

Kto tu pracuje?

ps -o user,pid,ppid,cmd -C apache2
USER       PID  PPID CMD
root     17990     1 /usr/sbin/apache2 -k start
www-data 17992 17990 /usr/sbin/apache2 -k start
www-data 17993 17990 /usr/sbin/apache2 -k start

Jeden proces jako root, reszta jako www-data. Root to kierownik recepcji: tylko on może otworzyć okienko numer 80, bo porty poniżej 1024 wymagają uprawnień administratora. Potem zatrudnia recepcjonistów, którzy obsługują gości, ale na zwykłym, ograniczonym koncie. Gdyby ktoś przejął recepcjonistę, dostaje klucze do jednego pokoju, a nie do całego hotelu.

[RHEL] Tam pracownicy działają jako użytkownik apache.

Czy recepcja słucha?

sudo ss -ltnp | grep ':80 '
LISTEN 0      511          0.0.0.0:80         0.0.0.0:*    users:(("apache2",pid=17993,fd=3),("apache2",pid=17992,fd=3),("apache2",pid=17990,fd=3))

0.0.0.0:80 znaczy: słucham na porcie 80 na wszystkich adresach. Recepcja otwarta.

Pierwszy test: curl

Zanim otworzysz przeglądarkę, sprawdź z samego serwera:

curl -I http://localhost/
HTTP/1.1 200 OK
Date: Tue, 03 Nov 2026 15:30:39 GMT
Server: Apache/2.4.58 (Ubuntu)

-I prosi tylko o nagłówki, bez treści strony. 200 OK, recepcja odpowiada. A cała rozmowa wygląda tak:

curl -v http://localhost/nie-ma-mnie
> GET /nie-ma-mnie HTTP/1.1
> Host: localhost
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Server: Apache/2.4.58 (Ubuntu)
< Content-Type: text/html; charset=iso-8859-1

Linie ze strzałką > to, co powiedział curl. Ze strzałką < to, co odpowiedział Apache. Zapamiętaj nagłówek Host:, bo w następnej lekcji dzięki niemu jeden Apache obsłuży kilka stron naraz.

Otwarcie portu 80

Na samym serwerze działa. Ale z innego komputera może już nie. Bo przed recepcją stoi ochroniarz z listą okienek, czyli zapora.

⚠️ Uwaga: jeśli łączysz się z serwerem przez SSH, a zapora jest wyłączona, NIE włączaj jej, zanim nie wpuścisz SSH. Inaczej ochroniarz wyrzuci Ciebie razem ze wszystkimi. Ćwicz na maszynie wirtualnej i miej otwartą drugą sesję.

[Ubuntu] ufw ma gotowe profile dla Apache:

sudo ufw app list
Available applications:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

Apache to port 80, Apache Secure to 443, Apache Full to oba:

sudo ufw app info 'Apache Full'
Ports:
  80,443/tcp
sudo ufw allow OpenSSH
sudo ufw allow 'Apache'
sudo ufw enable
sudo ufw status

[RHEL] firewalld ma usługi o nazwach http i https:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
sudo firewall-cmd --list-services

Usługa http w firewalld to dokładnie 80/tcp, a https to 443/tcp. Możesz też napisać wprost --add-port=80/tcp, efekt ten sam. Bez --permanent reguła działa do restartu. Z samym --permanent, bez --reload, reguła zadziała dopiero po restarcie. Firewalld lubi, jak się do niego mówi pełnymi zdaniami.

Jaki adres wpisać? localhost to „ja sam”, działa tylko na serwerze. Z zewnątrz potrzebujesz adresu IP serwera:

hostname -I
ip -br -4 a
192.0.2.2
lo               UNKNOWN        127.0.0.1/8
eth0             UP             192.0.2.2/24

lo pomijasz, to pętla zwrotna, czyli serwer gadający sam ze sobą. Interesuje Cię prawdziwa karta sieciowa, tu eth0. Na maszynie wirtualnej zwróć uwagę na tryb sieci: przy NAT komputer-gospodarz często nie widzi gościa bez przekierowania portów, przy sieci mostkowanej albo „host-only” widzi go od razu. Jak strona nie wchodzi, a curl na serwerze działa, to w dziewięciu przypadkach na dziesięć winna jest zapora albo sieć maszyny wirtualnej, a nie Apache.

Teraz z drugiego komputera:

curl -I http://ADRES_SERWERA/

Albo po prostu przeglądarka. Jeśli widzisz stronę „Apache2 Default Page: It works”, to działa. Na RHEL zobaczysz stronę testową Red Hata, bo folder ze stronami jest pusty i Apache pokazuje zastępczą.

Pierwsza strona

Gdzie Apache trzyma strony? W DocumentRoot, folderze głównym strony. Domyślnie na obu rodzinach to /var/www/html. Pamiętasz plan biurowca, FHS? /var to rzeczy zmienne, /var/www to strony.

ls -l /var/www/html

Na Ubuntu leży tam index.html, czyli ta domowa strona Apache. Plik index.html jest specjalny: jak gość prosi o /, a nie o konkretny plik, Apache daje mu właśnie index.html. To strona startowa folderu.

Podmieniamy:

echo '<h1>Witaj na moim serwerze!</h1>' | sudo tee /var/www/html/index.html
curl http://localhost/
<h1>Witaj na moim serwerze!</h1>

Gratulacje. Masz stronę internetową. Brzydszą niż strony z lat dziewięćdziesiątych, ale swoją.

Po każdej wizycie Apache zostawia ślad w dzienniku:

sudo tail -1 /var/log/apache2/access.log
127.0.0.1 - - [03/Nov/2026:16:35:26 +0100] "HEAD / HTTP/1.1" 200 229 "-" "curl/8.5.0"

[RHEL] /var/log/httpd/access_log i /var/log/httpd/error_log, z podkreślnikiem i bez .log.

Kto przyszedł (adres IP), kiedy, o co prosił, jaki kod dostał, ile bajtów i czym się przedstawił. Księga gości hotelu. Za chwilę, w typowym błędzie, przyda się jej siostra: księga skarg, czyli error.log.

Jak to działa pod spodem

Proces główny Apache, uruchomiony jako root, otwiera gniazdo na porcie 80, a potem tworzy procesy robocze i oddaje im obsługę połączeń jako www-data albo apache. Ubuntu 24.04 używa modułu wieloprocesowego event:

apache2ctl -M | grep mpm
 mpm_event_module (shared)

W trybie event każdy proces roboczy ma wiele wątków, a osobny wątek pilnuje połączeń, które tylko czekają. Recepcjonista nie stoi bezczynnie przy gościu, który zastanawia się nad menu. Obsługuje następnych, a do tamtego wraca, jak coś powie.

Kiedy przychodzi GET /index.html, Apache skleja DocumentRoot z adresem: /var/www/html + /index.html i otwiera ten plik na dysku. Z prawami użytkownika www-data. To bardzo ważne zdanie i zaraz zobaczysz dlaczego.

Narzędzie apachectl to pilot do Apache: configtest sprawdza konfigurację, graceful przeładowuje ją bez zrywania połączeń, -S pokazuje strony, -M moduły. Na Ubuntu nazywa się apache2ctl, ale apachectl to po prostu dowiązanie do niego, więc działają obie nazwy. Na RHEL jest apachectl.

Ściąga flag

KomendaFlagaCo robi
apt installapache2instalacja na Ubuntu
dnf installhttpdinstalacja na RHEL
systemctlenable --now apache2 / httpdwłącz na stałe i uruchom
systemctlreload apache2przeładuj konfigurację
apachectlconfigtestsprawdź składnię konfiguracji
apachectl-Mlista modułów
apache2 -v / httpd -vwersja
ss-ltnpkto słucha na jakim porcie
curl-Itylko nagłówki odpowiedzi
curl-vpokaż całą rozmowę HTTP
ufwallow 'Apache'otwórz 80 (Ubuntu)
ufwapp info 'Apache Full'jakie porty ma profil
firewall-cmd--permanent --add-service=httpotwórz 80 na stałe (RHEL)
firewall-cmd--reloadwczytaj stałe reguły

⚠ Typowy błąd

Dwa klasyki.

Pierwszy: 403 Forbidden. Skopiowałeś stronę, ale plik ma złe prawa. Odtwarzam:

sudo chmod 600 /var/www/html/index.html
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/
403

Księga skarg mówi wszystko:

sudo tail -1 /var/log/apache2/error.log
[core:error] [pid 30743:tid 140095485109952] (13)Permission denied: [client 127.0.0.1:51722] AH00132: file permissions deny server access: /var/www/html/index.html

chmod 600 znaczy: czytać może tylko właściciel, czyli root. A Apache czyta jako www-data. Recepcjonista dostał klucz do hotelu, ale nie do tego pokoju. Naprawa:

sudo chmod 644 /var/www/html/index.html

Pliki stron: 644, foldery: 755. Recepcjonista ma czytać, nie musi pisać. [RHEL] Na Red Hacie dochodzi jeszcze SELinux, który może dać 403 nawet przy idealnych prawach. To osobna historia, wrócimy do niej w lekcji o HTTPS.

Drugi: port zajęty. Apache nie chce wstać, a w logu:

(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down

Ktoś inny już siedzi w okienku numer 80. Najczęściej Nginx zainstalowany „na chwilę” pół roku temu. Szukasz winnego:

sudo ss -ltnp | grep ':80 '

I albo go zatrzymujesz (sudo systemctl disable --now nginx), albo przenosisz jednego z nich na inny port.

A przy każdym starcie na świeżej instalacji Ubuntu zobaczysz jeszcze to:

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message

To nie błąd, tylko ostrzeżenie: Apache nie wie, jak się nazywa. Naprawa w następnej lekcji, razem z resztą konfiguracji.

✎ Zadanie

Na swojej maszynie wirtualnej:

  1. Zainstaluj Apache, włącz go na stałe i sprawdź systemctl is-enabled oraz ss -ltnp, że słucha na porcie 80.
  2. Otwórz port 80 w zaporze (ufw albo firewalld) tak, żeby reguła przetrwała restart.
  3. Wrzuć do /var/www/html własny index.html i drugą stronę kontakt.html. Otwórz obie z innego komputera albo z telefonu w tej samej sieci.
  4. Znajdź w logu dostępu swoją wizytę z telefonu i odczytaj z niej adres IP telefonu oraz kod odpowiedzi.
Pokaż rozwiązanie

Instalacja i włączenie na stałe:

sudo apt install apache2            # Ubuntu
sudo dnf install httpd              # RHEL
sudo systemctl enable --now apache2 # albo httpd
systemctl is-enabled apache2
sudo ss -ltnp | grep ':80 '

is-enabled ma odpowiedzieć enabled. Port na stałe:

sudo ufw allow 'Apache'                              # Ubuntu
sudo firewall-cmd --permanent --add-service=http     # RHEL
sudo firewall-cmd --reload

Dwie strony:

echo '<h1>Witaj na moim serwerze!</h1>' | sudo tee /var/www/html/index.html
echo '<h1>Kontakt: admin@example.com</h1>' | sudo tee /var/www/html/kontakt.html

I wizyta z telefonu w logu. Wpis wygląda mniej więcej tak (adres i telefon będą u Ciebie inne):

sudo tail -f /var/log/apache2/access.log     # RHEL: /var/log/httpd/access_log
192.0.2.2 - - [03/Nov/2026:16:43:55 +0100] "GET /kontakt.html HTTP/1.1" 200 265 "-" "Mozilla/5.0 (Linux; Android 14; Pixel 8)"

Pierwsze pole to adres IP telefonu, 200 to kod odpowiedzi, a na końcu telefon sam się przedstawia, co to za model i system. Strony internetowe wiedzą o Tobie więcej niż ciocia na imieninach, a to dopiero pierwsza linijka logu. tail -f zostawia log otwarty i dopisuje nowe linie na żywo: otwierasz stronę na telefonie i widzisz, jak wizyta wpada na ekran serwera. Polecam, satysfakcja jak z pierwszego zapalonego światła w nowym mieszkaniu.

Co dalej

Jedna strona to dopiero początek. W następnej lekcji zaglądamy do środka konfiguracji Apache: VirtualHosty, czyli kilka stron na jednym serwerze, moduły, .htaccess, przekierowania i jak czytać logi, kiedy coś nie działa.