Развертывание и настройка веб-сервера на Linux: Nginx, PHP-FPM и MySQL/MariaDB | AdminWiki

Развертывание и настройка веб-сервера на Linux: Nginx, PHP-FPM и MySQL/MariaDB

08 апреля 2026 8 мин. чтения
Содержание статьи

Это пошаговое руководство по развёртыванию стека 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-run

Snap 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. Алгоритм диагностики:

  1. Проверьте статус службы PHP-FPM: sudo systemctl status php8.3-fpm.
  2. Сравните пути к сокету:
    В конфиге Nginx (fastcgi_pass) и в конфиге пула PHP-FPM (listen) должен быть указан один и тот же путь к Unix-сокету (например, /run/php/php8.3-fpm.sock).
  3. Проверьте права на сокет:
    ls -la /run/php/php8.3-fpm.sock
    Владелец и группа должны позволять чтение/запись пользователю, от которого работает Nginx (обычно www-data или nginx). Если права неверные, исправь listen.owner/group/mode или ACL в конфигурации пула, проверь php-fpm8.3 -t и затем перезагрузи FPM. Простой restart не исправляет неверную конфигурацию.
  4. Просмотрите логи:
    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.

Поделиться: