Как запустить несколько сайтов на Nginx с разными версиями PHP
Иногда на одном сервере нужно держать несколько сайтов с разными версиями PHP. Например, основной сайт уже готов к PHP 8.2, а старый проект на 1С-Битрикс пока стабильно работает только на PHP 7.4 или 8.1. Или наоборот: вы хотите обновить Битрикс и сначала проверить сайт на новой версии PHP, не ломая рабочий проект.
В Nginx это решается довольно просто: каждый сайт подключается к своему PHP-FPM сокету. Один виртуальный хост может работать через php7.4-fpm, другой — через php8.1-fpm, третий — через php8.2-fpm.
Зачем нужны разные версии PHP на одном сервере
Такая схема полезна в нескольких ситуациях:
- обновление сайта на 1С-Битрикс перед переходом на новую версию PHP;
- поддержка старого сайта, который не готов к современному PHP;
- тестирование проекта перед переносом на новую версию;
- размещение нескольких сайтов клиентов на одном VPS;
- постепенная миграция с PHP 7.4 на PHP 8.1 или 8.2;
- отдельная настройка лимитов и параметров PHP для разных сайтов.
Особенно актуально это для Битрикс. После обновления PHP могут всплыть старые ошибки в шаблонах, кастомных компонентах, модулях и обработчиках событий. Поэтому лучше сначала проверить сайт на тестовом домене или копии, а уже потом переключать боевой сайт.
Как работает связка Nginx и PHP-FPM
Nginx сам по себе не выполняет PHP-код. Он принимает запрос, отдает статические файлы и передает PHP-файлы в PHP-FPM.
PHP-FPM — это отдельный процесс, который обрабатывает PHP-скрипты. У каждой версии PHP может быть свой сервис:
php7.4-fpm
php8.1-fpm
php8.2-fpm
И у каждого сервиса есть свой сокет:
/run/php/php7.4-fpm.sock
/run/php/php8.1-fpm.sock
/run/php/php8.2-fpm.sock
Задача Nginx — передать конкретный сайт в нужный сокет.
Пример схемы
Допустим, на сервере есть три сайта:
old-site.ru— старый сайт на PHP 7.4;site.ru— основной сайт на PHP 8.1;test.site.ru— тестовая копия для проверки PHP 8.2.
Тогда схема будет такой:
old-site.ru → php7.4-fpm.sock
site.ru → php8.1-fpm.sock
test.site.ru → php8.2-fpm.sock
Установка нескольких версий PHP
На Debian или Ubuntu можно установить несколько версий PHP параллельно. Обычно для этого подключают репозиторий с нужными версиями PHP, а затем устанавливают отдельные пакеты.
apt update
apt install php7.4-fpm php7.4-cli php7.4-mysql php7.4-gd php7.4-mbstring php7.4-xml php7.4-zip
apt install php8.1-fpm php8.1-cli php8.1-mysql php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip
apt install php8.2-fpm php8.2-cli php8.2-mysql php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip
Для Битрикс обычно дополнительно нужны расширения:
mbstring;xml;curl;zip;gdилиimagick;mysqli;opcache;intl— если используется в проекте.
Проверяем, что PHP-FPM запущен
После установки нужно проверить статус сервисов:
systemctl status php7.4-fpm
systemctl status php8.1-fpm
systemctl status php8.2-fpm
Если сервис не запущен, его можно включить:
systemctl enable php8.2-fpm
systemctl start php8.2-fpm
Где лежат сокеты PHP-FPM
Обычно сокеты находятся в директории:
/run/php/
Проверить их можно командой:
ls -la /run/php/
В результате вы должны увидеть примерно такие файлы:
php7.4-fpm.sock
php8.1-fpm.sock
php8.2-fpm.sock
Пример конфига Nginx для сайта на PHP 8.1
Допустим, основной сайт должен работать на PHP 8.1.
server {
listen 80;
server_name site.ru www.site.ru;
root /var/www/site.ru;
index index.php index.html;
charset utf-8;
location / {
try_files $uri $uri/ /bitrix/urlrewrite.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Главная строка здесь:
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
Именно она определяет, через какую версию PHP будет работать сайт.
Пример конфига для тестовой копии на PHP 8.2
Теперь сделаем тестовый поддомен, который будет использовать PHP 8.2.
server {
listen 80;
server_name test.site.ru;
root /var/www/test.site.ru;
index index.php index.html;
charset utf-8;
location / {
try_files $uri $uri/ /bitrix/urlrewrite.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Отличие только в сокете:
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
Таким образом, основной сайт может работать на PHP 8.1, а тестовая копия — на PHP 8.2.
Пример для старого сайта на PHP 7.4
Если есть старый проект, который пока нельзя обновить, его можно оставить на PHP 7.4.
server {
listen 80;
server_name old-site.ru www.old-site.ru;
root /var/www/old-site.ru;
index index.php index.html;
charset utf-8;
location / {
try_files $uri $uri/ /bitrix/urlrewrite.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Как проверить, какая версия PHP используется
Самый простой способ — временно создать файл phpinfo.php в корне сайта:
<?php
phpinfo();
Затем открыть его в браузере:
https://site.ru/phpinfo.php
На странице будет указана версия PHP, через которую реально работает сайт.
После проверки файл обязательно нужно удалить:
rm /var/www/site.ru/phpinfo.php
Оставлять phpinfo.php на боевом сервере нельзя, потому что он показывает много технической информации о сервере.
Проверка конфигурации Nginx
После изменения конфигов нужно проверить синтаксис:
nginx -t
Если ошибок нет, перезагружаем Nginx:
systemctl reload nginx
PHP-FPM при смене сокета в конфиге Nginx обычно перезапускать не нужно, если сам сервис уже работает. Но после изменения настроек PHP нужно перезапустить конкретную версию:
systemctl restart php8.2-fpm
Настройки PHP для разных сайтов
У каждой версии PHP есть свои конфигурационные файлы:
/etc/php/7.4/fpm/php.ini
/etc/php/8.1/fpm/php.ini
/etc/php/8.2/fpm/php.ini
Это удобно: для старого сайта можно оставить одни настройки, а для нового — другие.
Например, для Битрикс часто приходится проверять:
memory_limit
upload_max_filesize
post_max_size
max_execution_time
max_input_vars
opcache.enable
date.timezone
После изменения php.ini нужно перезапустить нужный PHP-FPM:
systemctl restart php8.1-fpm
Отдельные PHP-FPM pool для сайтов
Более правильный вариант — использовать не только разные версии PHP, но и отдельные pool для каждого сайта.
Pool позволяет настроить:
- отдельного пользователя;
- отдельную группу;
- свой сокет;
- лимиты процессов;
- параметры окружения;
- отдельный лог ошибок.
Например, можно создать pool для сайта:
/etc/php/8.2/fpm/pool.d/site.conf
Пример содержимого:
[site]
user = www-data
group = www-data
listen = /run/php/php8.2-site.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
php_admin_value[error_log] = /var/log/php8.2-site-error.log
php_admin_flag[log_errors] = on
После этого в Nginx можно указать уже не общий сокет версии PHP, а отдельный сокет сайта:
fastcgi_pass unix:/run/php/php8.2-site.sock;
Это особенно полезно, когда на одном сервере несколько проектов и нужно разделить нагрузку.
Как обновлять Битрикс через тестовую копию
Безопасная схема обновления выглядит так:
- Сделать резервную копию файлов и базы данных.
- Создать тестовую копию сайта на поддомене.
- Подключить тестовую копию к новой версии PHP.
- Проверить публичную часть сайта.
- Проверить административную часть Битрикс.
- Проверить формы, корзину, авторизацию и интеграции.
- Исправить ошибки совместимости.
- После проверки переключить боевой сайт на новую версию PHP.
Например:
site.ru → PHP 8.1
test.site.ru → PHP 8.2
После успешной проверки можно заменить сокет в конфиге боевого сайта:
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
на:
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
Затем проверить конфигурацию и перезагрузить Nginx:
nginx -t
systemctl reload nginx
Что может сломаться при смене версии PHP
При обновлении PHP на сайте Битрикс чаще всего всплывают проблемы в кастомном коде:
- старые функции, которые больше не поддерживаются;
- ошибки типов;
- предупреждения в шаблонах компонентов;
- несовместимые модули;
- старые обработчики событий;
- ошибки в самописных классах;
- проблемы с кодировкой;
- ошибки в интеграциях с внешними сервисами.
Поэтому нельзя просто переключить PHP на боевом сайте и надеяться, что все заработает. Сначала лучше проверить сайт на копии.
Как быстро откатиться обратно
Преимущество схемы с разными сокетами в том, что откат занимает минимум времени.
Если после переключения на PHP 8.2 сайт начал ошибаться, можно вернуть прежний сокет:
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
Затем:
nginx -t
systemctl reload nginx
Это не заменяет резервную копию, но дает быстрый способ вернуть сайт на рабочую версию PHP.
Частые ошибки
Указали несуществующий сокет
Если в конфиге указан неправильный путь:
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
а такого сокета нет, сайт начнет отдавать ошибку 502 Bad Gateway.
Проверяйте список сокетов:
ls -la /run/php/
PHP-FPM не запущен
Даже если сокет указан правильно, сервис PHP-FPM должен быть запущен:
systemctl status php8.2-fpm
Изменили php.ini, но не перезапустили PHP-FPM
После изменения настроек PHP нужно перезапустить нужную версию:
systemctl restart php8.2-fpm
CLI использует другую версию PHP
Важно понимать: версия PHP для сайта и версия PHP в консоли могут отличаться.
Проверка в консоли:
php -v
Но сайт при этом может работать через другой PHP-FPM сокет.
Для запуска консольных скриптов конкретной версией можно использовать:
php8.1 script.php
php8.2 script.php
Чек-лист перед переключением боевого сайта
- Сделать резервную копию файлов.
- Сделать резервную копию базы данных.
- Проверить совместимость версии Битрикс с нужной версией PHP.
- Проверить установленные модули.
- Создать тестовую копию сайта.
- Подключить тестовую копию к новой версии PHP.
- Проверить публичную часть.
- Проверить административную часть.
- Проверить формы и интеграции.
- Проверить логи ошибок.
- Подготовить быстрый откат на старый сокет.
Вывод
Nginx позволяет достаточно просто держать на одном сервере несколько сайтов с разными версиями PHP. Для этого каждый виртуальный хост нужно направить в нужный PHP-FPM сокет через директиву fastcgi_pass.
Для Битрикс такая схема особенно полезна при обновлениях. Можно оставить боевой сайт на стабильной версии PHP, поднять тестовую копию на новой версии, проверить ошибки и только потом переключать основной сайт.
Главное — не обновлять PHP вслепую. Разные версии PHP на одном сервере дают возможность мигрировать аккуратно, без лишнего риска и долгого простоя сайта.
Комментарии