LAMP Stack — instalacja i konfiguracja na Ubuntu
Opublikowano: 9 kwietnia 2026 · Kategoria: VPS / Hosting
LAMP (Linux + Apache + MySQL + PHP) to klasyczny i sprawdzony stos technologiczny do
hostowania aplikacji webowych. Napędza większość instalacji WordPress, Drupal, Joomla i
niezliczone aplikacje PHP na świecie. Mimo że Nginx zyskuje popularność, Apache wciąż
wyróżnia się elastycznością (zwłaszcza .htaccess) i szeroką kompatybilnością.
Ten przewodnik przeprowadzi Cię przez pełną instalację na Ubuntu 22.04/24.04.
Krok 1: Instalacja Apache
apt update apt install -y apache2 # Sprawdzenie statusu systemctl status apache2 # Firewall — otwórz port 80 i 443 ufw allow 'Apache Full' ufw status # Test — otwórz http://IP_TWOJEGO_VPS w przeglądarce
Krok 2: Instalacja MySQL
apt install -y mysql-server # Zabezpieczenie instalacji (URUCHOM KONIECZNIE!) mysql_secure_installation # Kreator pyta o: # - poziom walidacji hasła (2 = silne) # - nowe hasło roota # - usunięcie anonimowych użytkowników (Y) # - wyłączenie zdalnego logowania root (Y) # - usunięcie bazy test (Y) # - reload uprawnień (Y) # Sprawdzenie wersji mysql --version
# Tworzenie bazy i użytkownika dla aplikacji mysql -u root -p CREATE DATABASE moja_aplikacja CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'silne-haslo-bazy'; GRANT ALL PRIVILEGES ON moja_aplikacja.* TO 'app_user'@'localhost'; FLUSH PRIVILEGES; EXIT;
Krok 3: Instalacja PHP
# PHP 8.2 z najpopularniejszymi modułami
apt install -y php8.2 php8.2-cli php8.2-fpm \
php8.2-mysql php8.2-curl php8.2-gd php8.2-mbstring \
php8.2-xml php8.2-zip php8.2-intl php8.2-bcmath
# Sprawdzenie wersji
php --version
# Moduł Apache dla PHP (mod_php)
apt install -y libapache2-mod-php8.2
# Restart Apache
systemctl restart apache2 Krok 4: Apache Virtual Host
Każda domena powinna mieć własny plik VirtualHost w /etc/apache2/sites-available/:
# /etc/apache2/sites-available/moja-domena.pl.conf
<VirtualHost *:80>
ServerName moja-domena.pl
ServerAlias www.moja-domena.pl
DocumentRoot /var/www/moja-domena.pl/public
<Directory /var/www/moja-domena.pl/public>
AllowOverride All # zezwól na .htaccess
Require all granted
Options -Indexes # wyłącz listowanie katalogów
</Directory>
ErrorLog ${APACHE_LOG_DIR}/moja-domena-error.log
CustomLog ${APACHE_LOG_DIR}/moja-domena-access.log combined
</VirtualHost> # Utwórz katalog i ustaw uprawnienia mkdir -p /var/www/moja-domena.pl/public chown -R www-data:www-data /var/www/moja-domena.pl # Aktywacja VirtualHost a2ensite moja-domena.pl.conf # Wyłączenie domyślnej konfiguracji (opcjonalne) a2dissite 000-default.conf # Włącz mod_rewrite (wymagany przez WordPress) a2enmod rewrite # Sprawdzenie konfiguracji apache2ctl configtest # Przeładowanie Apache systemctl reload apache2
PHP-FPM z mpm_event (wydajność)
Domyślna konfiguracja Apache używa mod_php z mpm_prefork — stara architektura,
która tworzy nowy proces na każde połączenie. Lepszym rozwiązaniem jest mpm_event + PHP-FPM:
# Przełącz z prefork na event a2dismod php8.2 mpm_prefork a2enmod mpm_event proxy_fcgi setenvif # Włącz PHP-FPM handler a2enconf php8.2-fpm # Uruchom PHP-FPM systemctl enable php8.2-fpm systemctl start php8.2-fpm # Restart Apache systemctl restart apache2 # Sprawdzenie czy PHP-FPM jest aktywny systemctl status php8.2-fpm
Testowanie instalacji PHP
# Utwórz testowy plik PHP echo "<?php phpinfo(); ?>" > /var/www/moja-domena.pl/public/info.php # Otwórz http://moja-domena.pl/info.php # Powinnaś zobaczyć stronę z informacjami o PHP # Po teście USUŃ plik — ujawnia konfigurację serwera! rm /var/www/moja-domena.pl/public/info.php
Bezpieczeństwo Apache
# /etc/apache2/conf-available/security.conf # Ukryj wersję Apache ServerTokens Prod ServerSignature Off # Wyłącz TRACE (ochrona przed XST) TraceEnable Off # Nagłówki bezpieczeństwa Header always set X-Content-Type-Options nosniff Header always set X-Frame-Options SAMEORIGIN Header always set X-XSS-Protection "1; mode=block"
# Włącz moduł headers (dla nagłówków bezpieczeństwa) a2enmod headers systemctl reload apache2
Darmowy certyfikat SSL (Let's Encrypt)
Produkcyjny LAMP Stack bez HTTPS to dziś standard, którego nie da się obronić - przeglądarki oznaczają strony HTTP jako "niezabezpieczone", a Google traktuje HTTPS jako sygnał rankingowy. Certbot automatyzuje cały proces łącznie z odnawianiem:
# Instalacja Certbota z pluginem Apache apt install -y certbot python3-certbot-apache # Wygenerowanie i instalacja certyfikatu (wymaga działającego VirtualHost + DNS wskazującego na serwer) certbot --apache -d moja-domena.pl -d www.moja-domena.pl # Certbot doda automatyczne przekierowanie HTTP -> HTTPS (opcja wybierana w kreatorze) # Test automatycznego odnawiania (certyfikaty ważne 90 dni) certbot renew --dry-run # Sprawdzenie timera odnawiania systemctl status certbot.timer
Firewall (UFW) - pełna konfiguracja
Krok 1 otwierał tylko ruch HTTP/HTTPS. Na produkcyjnym VPS warto od razu ustawić politykę domyślną i ograniczyć dostęp do SSH przed atakami brute-force:
# Domyślna polityka: blokuj przychodzące, zezwalaj na wychodzące ufw default deny incoming ufw default allow outgoing # SSH (zmień port jeśli używasz niestandardowego) ufw allow OpenSSH # Ogranicz próby logowania SSH (max 6 połączeń / 30s z tego samego IP) ufw limit OpenSSH # HTTP + HTTPS (Apache Full = porty 80 i 443) ufw allow 'Apache Full' # Aktywacja firewalla ufw enable # Weryfikacja reguł ufw status verbose
Rozwiązywanie typowych problemów (troubleshooting)
Cztery najczęstsze awarie świeżej instalacji LAMP i jak je szybko zdiagnozować - pełne wyjaśnienia z przyczyną i rozwiązaniem znajdziesz też w sekcji FAQ poniżej.
# 1. Apache nie startuje - sprawdź dokładny błąd systemctl status apache2 journalctl -xeu apache2 --no-pager | tail -30 apache2ctl configtest # musi zwrócić "Syntax OK" ss -tlnp | grep :80 # czy port 80 jest już zajęty # 2. 403 Forbidden - uprawnienia i konfiguracja Directory chown -R www-data:www-data /var/www/moja-domena.pl chmod -R 755 /var/www/moja-domena.pl tail -f /var/log/apache2/moja-domena-error.log # 3. PHP się nie wykonuje (przeglądarka proponuje pobranie pliku) apache2ctl -M | grep php # mod_php: powinien być widoczny php_module systemctl status php8.2-fpm # PHP-FPM: usługa musi być active (running) ls -la /run/php/ # PHP-FPM: socket musi istnieć # 4. MySQL "Access denied" / "Connection refused" systemctl status mysql mysql -u app_user -p -h localhost moja_aplikacja # test połączenia jako aplikacja grep bind-address /etc/mysql/mysql.conf.d/mysqld.cnf
Kopie zapasowe (backup) bazy danych i plików
Backup skonfigurowany po incydencie to za późno. Poniższy skrypt eksportuje bazę i pliki aplikacji, a crontab uruchamia go automatycznie co noc:
# /usr/local/bin/backup-lamp.sh
#!/bin/bash
set -e
DATE=$(date +%F)
BACKUP_DIR=/var/backups/lamp
mkdir -p "$BACKUP_DIR"
# Baza danych (--single-transaction = bez blokowania tabel InnoDB)
mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction moja_aplikacja \
> "$BACKUP_DIR/db-$DATE.sql"
# Pliki aplikacji
tar -czf "$BACKUP_DIR/www-$DATE.tar.gz" /var/www/moja-domena.pl
# Usuń kopie starsze niż 14 dni
find "$BACKUP_DIR" -type f -mtime +14 -delete # Uprawnienia + harmonogram (crontab -e) chmod +x /usr/local/bin/backup-lamp.sh # Codziennie o 3:00 w nocy 0 3 * * * /usr/local/bin/backup-lamp.sh >> /var/log/backup-lamp.log 2>&1
Kopie trzymane wyłącznie na tym samym serwerze nie chronią przed awarią dysku - docelowo przesyłaj je poza serwer (np. rsync na inny host albo storage obiektowy z retencją).
LAMP vs LEMP — kiedy co wybrać
| Cecha | LAMP (Apache) | LEMP (Nginx) |
|---|---|---|
| .htaccess | Pełne wsparcie | Brak (trzeba przepisać na server block) |
| Wydajność statycznych plików | Dobra | Lepsza |
| Zużycie RAM | Wyższe (prefork) | Niższe (event-driven) |
| WordPress | Działa natywnie | Wymaga konfiguracji fastcgi |
| Dokumentacja i support | Bardzo duże community | Duże community |