Это пошаговое руководство по развёртыванию стека LEMP: Linux, Nginx, MariaDB и PHP-FPM. Основной сценарий ниже рассчитан на новую Ubuntu 24.04 LTS с PHP 8.3 из репозитория дистрибутива. Разберём установку, виртуальный хост, HTTPS и диагностику. Производительность и безопасность необходимо проверять на своей конфигурации.
Пути и пакеты других дистрибутивов отличаются: заметки о RHEL не заменяют отдельную инструкцию для его версии. Перед изменениями рабочего сервера сохрани резервную копию и план восстановления.
Подготовка сервера и установка базовых компонентов
Для этого примера нужен VPS с Ubuntu 24.04 LTS и sudo. При выборе сервера можно сравнить Timeweb Cloud (партнёрская ссылка) с другими провайдерами по RAM, диску, резервным копиям и стоимости. Проверь рабочий SSH-сеанс и консоль восстановления; правила firewall меняй только после разрешения фактического SSH-порта и проверки второго подключения. Для сайта потребуются 80/443 и корректные DNS A/AAAA. Дополнительный PHP-репозиторий в этом сценарии не нужен.
Обновление системы и границы применимости
В Ubuntu 24.04 обнови пакеты:
sudo apt update && sudo apt upgrade -yДля RHEL 9 сначала выбери поддерживаемые Application Streams и пакеты по документации дистрибутива; установка Nginx не требует обязательного REMI. Не применяй RPM для другой major-версии. Также согласуй SELinux, пользователя процесса и пути сокета. Дальнейшие команды ниже выполняются на Ubuntu 24.04.
Установка Nginx, PHP-FPM и СУБД
Установите все необходимые компоненты стека одной командой. Обратите внимание на различия в именах пакетов.
Для Ubuntu 24.04 LTS:
sudo apt install nginx php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip mariadb-server -yПроверь версии и включи службы:
nginx -v
php-fpm8.3 -v
mariadb --version
sudo systemctl enable --now nginx php8.3-fpm mariadbБазовая настройка безопасности MySQL/MariaDB и PHP-FPM
Проверь настройки СУБД и PHP-FPM под своё приложение. Отдельная учётная запись базы ограничивает доступ, но общий пользователь www-data сам по себе не изолирует несколько сайтов.
Защита установки MySQL/MariaDB
В MariaDB современных Ubuntu root обычно входит локально через unix_socket: не нужно вслепую заменять эту схему паролем. При запуске sudo mariadb-secure-installation читай каждый вопрос; проверь отсутствие ненужных анонимных пользователей, тестовой базы и удалённого root-доступа. Не отвечай Y на всё автоматически.
Создание базы данных и пользователя для приложения
Войдите в консоль MySQL и выполните команды для создания отдельной базы данных и пользователя. Никогда не используйте root-учетную запись для веб-приложений.
sudo mariadbВ консоли MariaDB выполни SQL, заранее заменив пароль-заглушку уникальным секретом:
CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'REPLACE_WITH_UNIQUE_PASSWORD';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
EXIT;Конфигурация пула PHP-FPM для безопасности и изоляции
Отредактируйте основной файл пула. Для Ubuntu/Debian путь: /etc/php/8.3/fpm/pool.d/www.conf, для CentOS/RHEL: /etc/php-fpm.d/www.conf.
Найдите и измените следующие директивы:
; Пользователь процессов и сокет Ubuntu 24.04
user = www-data
group = www-data
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
; Стартовая оценка: пересчитай по памяти приложения
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3Сохрани прежний pool-файл. Проверь sudo php-fpm8.3 -t и только при успехе выполни sudo systemctl reload php8.3-fpm; при ошибке верни прежний файл.
Настройка виртуального хоста в Nginx и интеграция с PHP-FPM
Ключевой этап — создание конфигурации сайта, которая корректно передает PHP-скрипты на обработку в FPM. Конфигурация ниже задаёт связку через Unix-сокет; ошибку 502 нужно диагностировать по статусу FPM, пути, правам и логам.
Готовый конфигурационный файл Nginx для обработки PHP
Создайте файл виртуального хоста. Замените example.com на ваш домен и укажите правильный путь к корневой директории.
Для Ubuntu/Debian: /etc/nginx/sites-available/example.com
Для CentOS/RHEL: /etc/nginx/conf.d/example.com.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public_html;
index index.php index.html index.htm;
# Логирование
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Критически важный блок для обработки PHP
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php8.3-fpm.sock; # Проверьте путь к сокету!
fastcgi_index index.php;
include fastcgi_params;
# Эта директива часто является причиной ошибок
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ^~ /.well-known/acme-challenge/ {
default_type text/plain;
try_files $uri =404;
}
# Запрет доступа к скрытым файлам
location ~ /\. {
deny all;
}
# Кэширование статики
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|woff|ttf|svg)$ {
expires 30d;
add_header Cache-Control "public";
}
}Активируйте сайт (для Ubuntu/Debian) и проверьте конфигурацию:
# Для Ubuntu/Debian
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Для всех: проверка синтаксиса
sudo nginx -t
# Если вывод успешный, перезагрузите Nginx
sudo systemctl reload nginxПроверка конфигурации и прав доступа
Создайте корневую директорию сайта и тестовый PHP-файл для проверки связки.
sudo install -d -o root -g www-data -m 0755 /var/www/example.com/public_html
printf '%s\n' '<?php echo "PHP OK";' | sudo tee /var/www/example.com/public_html/test.php >/dev/null
sudo chmod 0644 /var/www/example.com/public_html/test.phpПроверь нужный виртуальный хост локально: curl -H "Host: example.com" http://127.0.0.1/test.php. Ожидается PHP OK. После проверки удали только созданный тестовый файл: sudo rm /var/www/example.com/public_html/test.php. Если не работает, проверь раздел диагностики. Не оставляй phpinfo() доступным из интернета.
Настройка HTTPS с бесплатным SSL от Let's Encrypt (Certbot)
Внедрение HTTPS стало стандартом. Certbot автоматизирует получение, установку и обновление SSL-сертификатов, избавляя администратора от рутины. Для более детальной ручной настройки SSL, включая работу с цепочками доверия и HSTS, обратитесь к нашему пошаговому руководству по ручной установке SSL-сертификатов на Nginx.
Установка Certbot и получение SSL-сертификата
Установите клиент Certbot в зависимости от вашего дистрибутива.
Ubuntu/Debian (рекомендуемый способ через snap):
sudo apt install snapd -y
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotПеред snap-установкой проверь, не установлен ли уже Certbot другим способом; используй один способ установки, как описано в официальной инструкции Certbot.
Получите и автоматически установите сертификат. Certbot сам изменит конфиг Nginx, добавив редирект с HTTP на HTTPS.
sudo certbot --nginx -d example.com -d www.example.comСледуйте интерактивным инструкциям. После успешного выполнения ваш сайт будет доступен по HTTPS.
Автоматическое обновление сертификатов
Срок сертификата проверяй по выданному сертификату; настрой и проверь автоматическое продление.
Сначала выполните тестовый прогон:
sudo certbot renew --dry-runSnap Certbot обычно уже устанавливает задачу автоматического продления. Проверь её через systemctl list-timers --all и настройки snap; не добавляй дублирующий cron. Dry-run проверяет продление, но сам не создаёт расписание.
Оптимизация производительности стека Nginx + PHP-FPM + MySQL
Базовые настройки рассчитаны на среднюю нагрузку. Для проектов с высокой посещаемостью необходима тонкая настройка. Эти параметры также критически важны при использовании Nginx в качестве балансировщика нагрузки в высокодоступном кластере.
Тонкая настройка PHP-FPM для вашей памяти
Ключевой параметр — pm.max_children. Рассчитайте его по формуле:pm.max_children = (Общая RAM - RAM для MySQL, Nginx, системы) / Средний размер памяти PHP-процесса.
Ниже независимые примеры, а не готовые нормативы по объёму RAM. Выбери и адаптируй только один набор в www.conf после измерений; не вставляй все три подряд. Учти запас памяти и пиковую нагрузку:
; Сервер с 1 ГБ RAM
pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 6
; Сервер с 2 ГБ RAM
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
; Сервер с 4 ГБ RAM
pm.max_children = 50
pm.start_servers = 8
pm.min_spare_servers = 8
pm.max_spare_servers = 16Узнать средний размер памяти процесса можно командой: ps --no-headers -o "rss,cmd" -C php-fpm8.3 | awk '{ sum+=$1 } END { printf ("%i\n", sum/NR/1024) }' (выдаст значение в МБ).
Буферизация и кэширование в Nginx
Добавьте в секцию http {} файла /etc/nginx/nginx.conf следующие директивы как пример для тестирования, без вложенного второго http и без строк многоточия. Изменяй существующие значения, а не дублируй их. Перед reload обязательно nginx -t:
http {
...
# Оптимизация буферов для клиентских запросов
client_body_buffer_size 16k;
client_max_body_size 20m;
# Буферизация ответов от FastCGI (PHP-FPM)
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
# Кэш метаданных открытых файлов
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
...
}Базовый тюнинг InnoDB в MySQL/MariaDB
Самая значимая настройка для производительности — размер буферного пула InnoDB. Отредактируйте файл конфигурации (/etc/my.cnf или /etc/mysql/mariadb.conf.d/50-server.cnf).
[mysqld]
# Выделите 70-80% от доступной RAM, если сервер выделен под БД.
# В совмещённом LEMP оставь запас для PHP, Nginx и ОС.
# Пример, который нужно пересчитать по измерениям:
innodb_buffer_pool_size = 256M
# Дополнительные настройки для SSD-дисков
innodb_flush_log_at_trx_commit = 1
innodb_log_file_size = 256M
innodb_flush_method = O_DIRECTИзмени существующие значения в существующей секции [mysqld], не добавляй дубликаты секции и параметров. Сохрани исходный файл, проверь поддержку директив установленной версией, выдели окно обслуживания и приготовь откат. После изменения перезапустите MariaDB: sudo systemctl restart mariadb.
Типичные проблемы после установки и их решение
Даже при точном следовании инструкциям могут возникнуть проблемы. Этот чеклист поможет быстро их диагностировать и устранить. Для комплексного анализа производительности всего стека рекомендуем наш гайд по диагностике и оптимизации веб-приложений.
Ошибка 502 Bad Gateway: причины и исправление
Самая частая проблема в связке Nginx + PHP-FPM. Алгоритм диагностики:
- Проверьте статус службы PHP-FPM:
sudo systemctl status php8.3-fpm. - Сравните пути к сокету:
В конфиге Nginx (fastcgi_pass) и в конфиге пула PHP-FPM (listen) должен быть указан один и тот же путь к Unix-сокету (например,/run/php/php8.3-fpm.sock). - Проверьте права на сокет:
ls -la /run/php/php8.3-fpm.sock
Владелец и группа должны позволять чтение/запись пользователю, от которого работает Nginx (обычноwww-dataилиnginx). Если права неверные, исправь listen.owner/group/mode или ACL в конфигурации пула, проверь php-fpm8.3 -t и затем перезагрузи FPM. Простой restart не исправляет неверную конфигурацию. - Просмотрите логи:
sudo tail -f /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm --since "5 minutes ago"
Проблемы с правами на файлы и директории
Ошибки 403 Forbidden или невозможность загрузки файлов часто связаны с правами.
- Корректный владелец: Код сайта может принадлежать root или пользователю развёртывания; PHP-FPM и Nginx получают чтение. Запись предоставляй только каталогам, которым она действительно нужна, например кэшу/загрузкам.
sudo chown -R root:www-data /var/www/example.com/public_html sudo find /var/www/example.com/public_html -type d -exec chmod 755 {} \; sudo find /var/www/example.com/public_html -type f -exec chmod 644 {} \; - Для директорий кэша/загрузок может потребоваться разрешение на запись для веб-сервера. Для следующего необязательного примера нужны установленный пакет acl и существующий каталог storage. Применяй ACL только к каталогу данных, которому нужна запись, а не ко всему коду:
sudo setfacl -R -m u:www-data:rwx /var/www/example.com/public_html/storage/
Если вы столкнулись с более сложными атаками или нуждаетесь в продвинутой защите веб-сервера, изучите наше практическое руководство по защите Nginx в 2026 году, где рассмотрены настройки WAF, rate limiting и защита от DDoS.