В этом руководстве подробно описано, как отделить среду выполнения PHP от вашей хостовой операционной системы. Запустив актуальную версию PHP внутри Docker-контейнера и сохранив при этом нативный веб-сервер Apache для работы с SSL и маршрутизацией, вы сможете устранить критические уязвимости PHP (такие как PHP2Shell) без обновления или замены хостовой ОС.
Этот подход особенно полезен при работе на устаревшем хосте, который нельзя легко обновить или заменить. Например, Debian 11 предоставляет только PHP 7.4, для которого патч от этой проблемы не выпускался. Очевидно, идеальным решением был бы полный отказ от ОС, достигшей конца жизненного цикла (EOL). Однако это не всегда осуществимо сиюминутно, а продолжать использовать уязвимую версию PHP — нецелесообразно.
Шаг 1: Подготовка хостовой системы
Сначала необходимо включить необходимые модули связи в вашей нативной установке Apache на хосте, чтобы он мог перенаправлять запросы PHP на бэкенд FastCGI.
# Enable the required Apache proxy modules
sudo a2enmod proxy
sudo a2enmod proxy_fcgi
# (Optional) Disable your native old PHP module to free system memory
# Replace "7.4" or "8.0" with your specific native system version
sudo a2dismod php7.4
# Restart Apache to load the changes
sudo systemctl restart apache2
Шаг 2: Создание развертывания Docker Compose
Убедитесь, что у вас установлен Docker.
Мы будем использовать Docker Compose для описания среды выполнения. Это сделает вашу конфигурацию воспроизводимой и легко обновляемой.
Создайте файл docker-compose.yaml в вашем административном каталоге (например, /home/docker/php-fpm/ ):
services:
php-fpm:
image: hermsi/alpine-fpm-php:8.5
container_name: php-fpm
restart: unless-stopped
user: "1000:33"
network_mode: "host"
volumes:
- ./zz-listen.conf:/usr/local/etc/php-fpm.d/zz-listen.conf:ro
- ./zz-security.ini:/usr/local/etc/php/conf.d/zz-security.ini:ro
- /var/www:/var/www
Примечание. Запустите id -u [username] и getent group www-data на вашей хостовой системе, чтобы узнать точные числовые ID для поля user: .
Измените директиву volumes: так, чтобы она указывала на ваш Apache DocumentRoot . Добавьте любые дополнительные тома, которые могут потребоваться для других виртуальных хостов.
Создайте файл zz-listen.conf в том же каталоге, где находится файл compose, со следующим содержимым:
[www]
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
Это привяжет службу FastCGI к интерфейсу замыкания на себя (loopback). Без этого явного ограничения прослушивания FastCGI может оказаться доступен через публичные интерфейсы сервера. Приведенная выше конфигурация разрешит локальные подключения от Apache и предотвратит прямой внешний доступ к прослушивателю FastCGI.
Также создайте файл zz-security.ini :
; do not advertise php version
expose_php = Off
; do not output errors in response
display_errors = Off
display_startup_errors = Off
; send errors to docker log
log_errors = On
error_log = /proc/self/fd/2
; mitigate CVE-2026-115560
session.upload_progress.enabled = 0
Эти параметры представляют собой разумные настройки по умолчанию для продакшена публичного PHP-приложения. Используйте этот шаблон для изменения любых других параметров, которые вы хотите настроить (например, upload_max_filesize ).
Шаг 3: Запуск службы FastCGI
Запустите контейнер в фоновом режиме:
sudo docker-compose up -d
Примечание. Я использовал устаревшую команду docker-compose . Если вы следуете этому руководству, велика вероятность, что у вас также установлена старая версия Docker, поэтому это необходимо. Если вы используете Docker версии 23 или новее, команда должна быть docker compose (содержит пробел).
Шаг 4: Настройка хостового Apache для перенаправления запросов PHP в PHP-FPM
Обновите файл конфигурации VirtualHost нативного Apache ( /etc/apache2/sites-available/your-site.conf ), чтобы напрямую связать ваши фронтенд-домены с обработчиком сокетов в контейнере.
Сопоставив тома DocumentRoot в файле compose, Apache и ваш контейнер получают абсолютно одинаковую структуру корневого каталога, а пути выполнения выстраиваются идеально:
<VirtualHost *:443>
ServerName yourdomain.com
DocumentRoot /var/www
# ... Your existing SSL configuration rules ...
# The Core Mechanism: Intercept all PHP requests and forward them
# directly to the container listening locally on port 9000
<FilesMatch "\.php$">
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
<Directory /var/www>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Перезагрузите Apache, чтобы применить новую конфигурацию маршрутизации:
sudo systemctl reload apache2
Основные архитектурные подводные камни и их решения
Ловушка сокета
localhost(Ошибка 2002):
Когда конфигурация PHP-приложения (например, Nextcloud или WordPress) использует строкуlocalhostв качестве адреса базы данных, движок PHP принудительно устанавливает соединение через физический файл сокета файловой системы (mysqld.sock). Поскольку этого файла не существует внутри контейнера, подключения будут завершаться с ошибкой. Решение: Измените настройки базы данных в приложении сlocalhostна явный сетевой loopback IP127.0.0.1.Матрица прав доступа к базе данных:
Убедитесь, что ваш нативный сервер базы данных (MariaDB/MySQL) настроен на прием сетевых подключений с интерфейса замыкания на себя (loopback) и что вашей учетной записи базы данных явно предоставлены привилегии для аутентификации с хоста127.0.0.1по стандартному TCP.Эффект подавления логов:
По умолчанию контейнеризованные PHP-приложения выводят основные системные предупреждения напрямую в стандартные потоки вывода (stdout/stderr). Если вы ищете ошибки выполнения, запуститеdocker compose logs php-fpmилиdocker logs php-fpm, чтобы просматривать трассировку ошибок вашего приложения в реальном времени.
Будущие обновления
Когда выйдет следующий патч безопасности или новый мажорный/минорный релиз PHP, обновить всю среду будет просто. Тег версии PHP, используемый в docker-compose.yaml , установлен как :8.5 . Скачивание образа с Docker Hub автоматически загрузит последний патч-релиз (на данный момент 8.5.12). Если вы хотите использовать более новую версию, просто измените этот тег на :8.6 или в будущем на :9.0 , когда они появятся. Обязательно предварительно проверьте хостящиеся приложения на наличие проблем совместимости.
sudo docker-compose pull && \
sudo docker-compose up -d
Комментарии (0)
Пока нет комментариев — будьте первым.