Наверное, многие сталкивались с ситуацией, когда среди проектов, работающих на современном ПО, остается пара полузабытых, а держать отдельную машину под них не хочется. Вариантов решения — масса, но в службе поддержки хостинг-компании данная проблема не теряет своей актуальности. Мои коллеги разработали скрипт, помогающий добавить нужную версию PHP в VestaCP буквально за пару минут. Данный метод уже зарекомендовал себя с хорошей стороны, и он продолжает радовать сотрудников поддержки. Самое время его опубликовать и помочь всем, кто столкнулся с подобной проблемой.

Для того чтобы воспользоваться решением, достаточно скопировать одну строчку в терминал, но мы рассмотрим чуть подробнее, как всё это работает.

Установка

Выполняется командой:

git clone https://github.com/kotpoliglot/vestaphpinstaller.git && cd vestaphpinstaller && chmod +x dockerize.sh && bash dockerize.sh -s --5.6

Будет установлен (если не был установлен ранее) docker через унифицированный инсталлятор (проверялся на CentOS7 и Ubuntu).

Последний аргумент в команде — желаемая версия PHP. В настоящий момент доступны версии PHP: 5.2, 5.3, 5.4, 5.5, 5.6, 7.0, 7.1, 7.2 и 7.3. Скрипт создаст шаблон для Vesta и два сервисных файла: docker.httpd и docker.php.56.

Все сервисы выполняют установку/обновление образов, в связи с чем первый запуск (например, подключение шаблона в “Весте”) либо перезапуск при наличии обновлений может занять некоторое время.

PHP запускается от имени www-data. На хосте будет создан (если еще нет) соответствующий пользователь. Владелец директории сайта будет изменен на www-data, группа останется прежняя. Также будет создана директория /opt/docker/ для хранения конфигурационных файлов.

В итоге мы потратим ~700 Мб на установку самого докера и около ~300Мб на образы, но получим прирост производительности. Результаты измерения производительности средствами Bitrix в 1.5-2 раза выше для связки VestaCP + Docker, чем при использовании аналогичной версии PHP в качестве модуля Apache.

Установка на одноядерный процессор

При установке докер-контейнера на сервер с одноядерным процессором (cpu=1) не будет автоматически запускаться контейнер PHP.
В таких случаях необходимо отредактировать файл /etc/systemd/system/docker.php.56.service (где 5.6 - установленная версия PHP):

--cpus=2 изменить на --cpus=1

Далее перезапустить докер:

systemctl stop docker
systemctl start docker

После чего переключить на нужную версию PHP в панели VestaCP. В случае если нужная версия уже выбрана, то необходимо переключить на дефолтную, сохранить и снова переключить на нужную версию PHP.

Схема работы

Схема работы выглядит следующим образом:

Nginx -> apache в контейнере -> php-fpm в контейнере.

Apache потребовалось запаковать в контейнер (~80mb) из-за различий версий между CentOS и Apache. Версия в Centos не позволяет корректно проксировать запросы на fpm.

Apache запускается на порту 9080, поэтому скрипт редактирует конфигурацию nginx. Переключение на стандартный шаблон Vesta (default) вернет прежний порт (8080).

PHP запускается на 9000+version, то есть 9056, 9070, 9072 и т.д.

HTTPD

httpd запускается следующим образом:

docker run --rm --network host
-v /home:/home
-v /var/log/httpd/domains:/var/log/apache2/domains
-v /opt/docker/conf/web:/usr/local/apache2/conf/vhosts
--name docker-httpd kotpoliglot/php:httpd

В /opt/docker/conf/web лежат хосты, httpd в контейнере с минимальным набором модулей из-за экономии ресурсов, хосты для контейнеров хранятся в /opt/docker/conf/web, в директории Vesta (/home/admin/conf/web/) создается пустой файл.

PHP

PHP запускается следующим образом:

docker run --rm --network host --cpus=2
  -v /etc/passwd:/etc/passwd
  -v /etc/group:/etc/group
  -v /etc/hosts:/etc/hosts
  -v /var/lib/mysql/mysql.sock:/var/run/mysqld/mysqld.sock
  -v /opt/docker/conf/php/56/php.ini:/usr/local/etc/php/conf.d/docker.ini
  -v /home:/home --name php-56 kotpoliglot/php:56

passwd и group передаются в контейнер из-за различных требований к uname и uid в CentOS и Ubuntu.

/etc/hosts — внешние адреса доменов Vesta, они нужны в контейнере для корректной работы сокетов в Bitrix, например. Файл обновляется при каждом переключении шаблонов в Vesta.
/opt/docker/conf/php/56/php.ini — файл, с помощью которого можно повлиять на параметры PHP в контейнере.

Добавление модулей и пакетов

При необходимости можно добавить тот или иной модуль или пакет в контейнер. Образы собраны на основе alpine для экономии ресурсов. Пакеты ставятся через apk, например, создаем Dockerfile cо следующим содержимым:

FROM kotpoliglot/php:56
RUN apk add --no-cache libpng-dev

Затем сохраняем файл и выполняем:

docker build -t kotpoliglot/php:56 .

PHP

В случае, если требуется модуль для PHP, в контейнерах есть набор скриптов docker-php-ext-configure, docker-php-ext-install и docker-php-ext-enable (описание).

Установка будет выглядеть следующим образом: создаем Dockerfile в произвольной директории со следующим содержимым:

FROM kotpoliglot/php:56
RUN docker-php-ext-install zip

Затем пересоздаем образ:

docker build -t kotpoliglot/php:56 .

Будет создан новый образ с прежним именем и установленным модулем.

сервисном файле стоит удалить ExecStartPre=/usr/bin/docker pull kotpoliglot/php:56, чтобы запускался локальный образ, а не заново скачанный с DockerHub.

Сервисные файлы доступны по пути /etc/systemd/system/.

Если инструмент показался вам полезным — дайте знать, мы подготовим подобное решение, например, для панели ISPConfig.

Комментарии (9)


  1. linux_art
    27.07.2021 10:49

    > Nginx -> apache в контейнере -> php-fpm в контейнере.

    Зачем в этой цепочке apache?


    1. KotPoliglot Автор
      27.07.2021 11:08

      VestaCP изначально работает в связке Nginx + Apache, но из-за того, что версия Apache в CentOS не позволяет корректно проксировать запросы на PHP-FPM пришлось добавить версию в контейнере, которая это успешно делает.


      1. linux_art
        27.07.2021 11:16

        А не проще было проксировать напрямую с Nginx?


        1. KotPoliglot Автор
          27.07.2021 11:53

          В данном случае не проще, ведь если обращаться с Nginx на PHP-FPM мы теряем возможность использовать .htaccess файлы и у нас появляется необходимость в кастомных конфигурациях Nginx для каждого сайта.

          Если хочется использовать Nginx+PHP-FPM рекомендую посмотреть на ISPconfig - отличная бесплатная панель управления хостингом, с большим функционалом, чем у VestaCP


          1. grayfolk
            27.07.2021 12:06

            мы теряем возможность использовать .htaccess файлы и у нас появляется необходимость в кастомных конфигурациях Nginx для каждого сайта

            И в чем тут проблема? .htaccess - это наследие тех времен, когда не было фреймворков с единой точкой входа и было огромное количество самописа. Сейчас же максимум, чем отличаются конфигурации - это public-папкой.


            1. KotPoliglot Автор
              27.07.2021 13:02

              Так оно и есть, данное решение как раз и для поддержки старых проектов, в которых к тому же в том же .htaccess может быть целая история переименования разделов интернет магазина, разные поддомены в разных папках и т.д...


      1. grayfolk
        27.07.2021 12:01
        +1

        В Весте при установке можно выбрать nginx+apache, nginx+php-fpm или просто apache - вероятно, с mod_php.


  1. grayfolk
    27.07.2021 12:18
    +1

    Веста последний раз обновлялась более полутора лет назад. Присутствуют незакрытые уязвимости, более трех сотен открытых issue на гитхабе, отсутствие поддержки Ubuntu 20, Debian 10. Вряд ли на данный момент Веста - хороший выбор для панели.

    рекомендую посмотреть на ISPconfig

    Как по мне, есть и получше альтернативы - форки Весты - HestiaCP, myVesta, китайская aaPanel, BrainyCP.

    PHP 5.6

    Это, конечно, да, PHP5 в 2021 году. Уже поддержка 7.2 прекращена.


  1. werter_l
    31.07.2021 18:13

    vestacp давно протухла — hestiacp в помощь.