Manuals
RU EN

Сервер · 83

Nginx + PHP-FPM для скрипта

Сервер 5 мин чтения

На VDS готовый PHP-скрипт чаще стоит за Nginx + PHP-FPM, чем за «чистым Apache из mid-2000s». Nginx отдаёт статику, PHP уходит в пул FPM через FastCGI. Shared иногда прячет это за панелью; на своём сервере конфиг видите вы.

Ниже каркас, достаточный чтобы поднять скрипт Microscript. Тонкий тюнинг под тысячy RPS сюда не входит — сначала сделайте чтобы работало и логировалось.

Пакеты

На Debian/Ubuntu условно:

nginx
php8.2-fpm php8.2-mysql php8.2-mbstring php8.2-xml php8.2-gd php8.2-curl

Версию подставьте свою 8.x. Требования модулей: PHP/MySQL. MySQL/MariaDB — отдельно. Выбор машины: VDS, root: VPS.

server-блок: идея

  • server_name — ваш домен;
  • root — каталог скрипта с index.php;
  • index index.php;
  • location для PHP → fastcgi_pass на сокет или порт пула;
  • ЧПУ: try_files на index.php, если скрипт так работает;
  • client_max_body_size — под загрузки (часто 32m–64m).

Точный snippet зависит от продукта (наличие public/, правила rewrite). Не копируйте слепо WordPress-конфиг, если структура другая.

PHP-FPM пул

Отдельный пул под пользователя сайта лучше, чем всё от www-data вперемешку. Сокет вроде /run/php/php8.2-fpm-site.sock. В Nginx:

fastcgi_pass unix:/run/php/php8.2-fpm-site.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

После смены пула — права на каталоги upload под этого пользователя: chmod.

.htaccess не работает

Правила Apache из комплекта сами не подхватятся. Переносите rewrite в Nginx. Симптом после переезда с shared Apache: главная жива, внутренние URL 404. Это не «сломанный PHP».

Временный костыль «поставить Apache» тоже вариант, если так быстрее закрыть запуск. Долгосрочно Nginx+FPM нормален.

Логи

Смотрите оба:

  • access/error nginx;
  • лог PHP-FPM / php_admin_value[error_log].

502 Bad Gateway — FPM не запущен или неверный сокет. 500 — уже PHP/скрипт: ошибка 500. Ошибки БД: MySQL.

Upload «пусто» при живом PHP. Часто client_max_body_size меньше файла, nginx режет запрос до скрипта. В error.log nginx будет про body. Параллельно проверьте upload_max_filesize в php.ini пула.

SSL

Certbot умеет дописать ssl в server-блок: SSL на сайте. После выпуска проверьте редирект и смешанный контент в админке.

Безопасность краткая

  • Запрет выполнения PHP в каталоге upload.
  • Не отдавать .env, конфиги, .git.
  • Firewall: порты.

Деплой скрипта

  1. root на каталог, файлы залиты.
  2. База создана, конфиг прописан.
  3. nginx -t && systemctl reload nginx.
  4. Установщик или вход в админку — установка.
  5. Cron отдельно — cron.

Перенос со старого Apache-хостинга: перенос. Локально под Windows Nginx не обязателен — там Apache в MicroServer.

Типичный location для PHP

Каркас, от которого отталкиваемся на большинстве VDS:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php/php8.2-fpm-site.sock;
    fastcgi_read_timeout 120s;
}

Если скрипт лежит не в корне домена, а в подкаталоге — root и try_files должны смотреть туда же. Путаница с alias и root на подпапках даёт пустой ответ или «No input file specified». Тогда в логе FPM путь к скрипту не совпадает с реальным файлом на диске.

fastcgi_read_timeout поднимают, когда админка гоняет долгий импорт. Иначе nginx отдаст 504, а PHP ещё работает — в базе получите полуимпорт и потом будете гадать.

Статика и запрет лишнего

Картинки, css, js Nginx отдаёт сам — до PHP они не должны доходить. Отдельно запретите доступ к служебному:

location ~ /\.(git|env|ht) {
    deny all;
}

В каталоге upload лучше запретить исполнение PHP. Иначе загруженный файл с расширением .php станет бэкдором. На Apache это часто делали через .htaccess; на Nginx — отдельный location с location ~* /upload/.*\.php$ и deny, либо вынос загрузок на другой root без обработки PHP.

Несколько сайтов на одном VDS

На каждый домен — свой server-блок и желательно свой пул FPM. Иначе один сайт забьёт pm.max_children, и соседний магазин начнёт отвечать 502. В пуле смотрите pm, pm.max_children, pm.max_requests. На 2 GB RAM жадничать с max_children опасно: PHP-FPM + MySQL лягут вместе.

Логи лучше разнести по сайтам: свой access/error на vhost. Когда в тикете пишут «вчера после обеда 500», без раздельных логов вы ищете иголку в общем error.log на пять доменов.

Связка с установкой скрипта

Пока nginx -t не проходит, установщик в браузере не откроете. Сначала зелёный nginx -t, reload, проверка curl -I http://127.0.0.1 -H 'Host: example.com'. Потом уже база и форма установки.

Если документ рут указывает на пустую папку, а файлы лежат уровнем выше — получите welcome-страницу Nginx или 403. Это не баг Microscript. Поднимите root на каталог с index.php.

После успешного запуска повесьте cron от пользователя сайта, не от root без нужды. SSL через Certbot допишет listen 443 — проверьте, что второй server-блок не перетёр ваш root. Бывает, Certbot создаёт дубль и сайт внезапно смотрит в /var/www/html.

Диагностика 502 и 504

  • 502 — сокет мёртв, пул не стартовал, неверное имя sock, SELinux/права на sock.
  • 504 — таймаут; долгий скрипт или FPM завис в ожидании MySQL.
  • В error.log nginx строка connect() to unix:... failed — смотрите путь sock и status php-fpm.

systemctl status php8.2-fpm и хвост лога пула обычно закрывают вопрос быстрее, чем перезагрузка всего сервера «на всякий случай».

Когда PHP уже отвечает, а скрипт орёт про базу — это не Nginx. Идите в ошибку MySQL. Когда белый экран при 200 — display_errors и лог приложения: ошибка 500.

Панели

ISPmanager и аналоги генерируют nginx-конфиг сами. Править его руками можно, но после «пересохранения домена» в панели ваши правки иногда откатываются. Либо правьте через шаблоны панели, либо держите include-файл, который панель не затирает. На shared с Apache этот раздел вам меньше нужен — там .htaccess. На своём VDS без понимания fastcgi_pass скрипт «просто не открывается», хотя файлы залиты.

Бэкап конфигов nginx вместе с сайтом не помешает: бэкап. После миграции на другой VDS конфиг переносится не слепо — пути и sock другие: дамп базы отдельно от vhost.

Частые вопросы

Настроить nginx php-fpm для скрипта?

На VDS скрипты чаще крутятся за Nginx+PHP-FPM, не на shared-хостинге.

Сколько времени занимает «Nginx + PHP-FPM для скрипта»?

Ориентир по тексту мануала — около 5 мин. На практике зависит от хостинга и подготовки базы.

Нужен ли отдельный сервер?

Для большинства скриптов достаточно хостинга или VDS с PHP и MySQL. Подбор сервера — в разделе VDS и требованиях к PHP/MySQL.

Какой vds для скрипта доски объявлений?

Разбор рядом в мануале по этому запросу. какой vds для скрипта доски объявлений

Vps с root для php скрипта?

Разбор рядом в мануале по этому запросу. vps с root для php скрипта

Раздел
VDS и сервер для PHP

Сервер под PHP/MySQL: от выбора тарифа до Nginx и firewall.