Обновление PHP в окружении BitrixVM с использованием Docker

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Введение

В данной статье я бы хотел рассмотреть проблему обновления PHP в виртуальной машине BitrixVM, и действия, которые возможно применить если выполнение переезда на машину с обновленным ПО невозможно. Надеюсь, что статья будет полезна для вас.

Предыстория

Несколько месяцев назад перед нами встала задача обновления PHP до версии 7.4 на одном из наших проектов. Проект был расположен внутри виртуальной машины с развернутой на ней BitrixVM версии 7.2.2. Заглянув в меню Битрикс при обращениях к скрипту /root/menu.sh было обнаружено, что обновление PHP невозможно без обновления Битрикс окружения. При этом само обновление окружения выполняется из бета репозиториев, так как текущая стабильная версия не поддерживала работу с PHP версии 7.4 согласно курсу:

https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=32&LESSON_ID=12862

Прошерстив форумы Битрикс, мы не нашли конкретного ответа, когда будет выполнено обновление BitrixVM до стабильной версии с поддержкой с PHP 7.4. В связи с чем, нами было принято решение обновить версию окружения до актуальной беты на одном из виртуальных серверов разработки, предварительно сделав snapshot.

Проблема BitrixVM в том, что это готовое решение, использующее Ansible скрипты для выполнения операций. При этом в случае нарушения работы скрипта операция будет прервана, а идентифицировать ошибку крайне сложно, как и понять на какой именно стадии она возникла.

BitrixVM хранит лог выполняемых задач по пути /opt/webdir/temp/, в ходе выполнения обновления окружения в логе возникали различные ошибки, вызывавшие нарушение процесса обновления. Поиск и решение подобных ошибок занимало достаточный период времени. Как пример, возникали ошибки подключения репозитория:

TASK [common : get server options] *********************************************

fatal: [96410.local]: FAILED! => {"failed": true, "msg": "The conditional check 'common_manage == 'update_packages'' failed. The error was: cannot import name shlex_quote\n\nThe error appears to have been in '/etc/ansible/roles/common/tasks/update_packages.yml': line 3, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n# configure oldkernel limits\n- name: get server options\n  ^ here\n"} 

to retry, use: --limit @/etc/ansible/common.retry
4. Disable the repository permanently, so yum won't use it by default. Yum\n        will then just ignore the repository until you permanently enable it\n        again or use --enablerepo for temporary usage:\n\n            yum-config-manager --disable <repoid>\n        or\n            subscription-manager repos --disable=<repoid>\n\n     5. Configure the failing repository to be skipped, if it is unavailable.\n        Note that yum will try to contact the repo. when it runs most commands,\n        so will have to try and fail each time (and thus. yum will be be much\n        slower). If it is a very temporary problem though, this is often a nice\n 

Второй проблемой было то, что в случае если обновление из Бета репозиториев было выполнено неудачно и нарушало работу проекта, скрипты BitrixVM не предусматривают откат до стабильной версии, согласно информации:

https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=37&TYPE=Y

Обратного отката установленной бета-версии к текущей стабильной нет, т.е если вы перешли, например, на бету 7.4.13, то вернуться к стабильной 7.4.4 нельзя. В этом случае чтобы перейти на стабильную версию, нужно дождаться релиза стабильной версии, новее беты, или установить стабильную версию заново. Например для бета-версии 7.4.13, нужно ждать стабильную версию 7.5.

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

Когда обновление до Бета версии прошло удачно, всплыла проблема при разворачивании новой версии PHP. Ansible роли виртуальной машины Битрикс предусматривают откат до предыдущей версии PHP, для этого в меню виртуальной машины есть, например следующие пункты:

Rollback PHP to version 5.6 
Rollback PHP to version 7.2

Однако на тестовом стенде мы также тестировали откат до предыдущих версий, эти операции также завершались различными ошибками. Ниже пример одной из них:

TASK [web : additional gathering facts] ****************************************

fatal: [96410.local]: FAILED! => {"changed": false, "module_stderr": "", "module_stdout": "{\"ansible_facts\":{\"bx_system_type\":\"10\",\"os_version\":\"7\",\"bx_memsystem_type\":\"8192\",\"bx_memory\":\"8009

812\",\"bx_version\":\"7.4-11\",\"bx_base_version\":\"7\",\"bx_package_name\":\"bitrix-env\",\"link_eth0\":\"yes\",\"speed_eth0\":\"\",\"addr_eth0\":\"176.57.215.253 92.53.127.54\",\"bx_bitrix_uid\":\"600\",\"rpm_bin\":\"/bin/rpm\",\"nginx_version\":\"1.12.2\",\"nginx_ssl\":\"ssl http2\",\"push_type\":\"nginx-push-stream-module\",\"push_status\":\"not_installed\",\"push_security_key\":\"\",\"push_host\":\"\",\"push_port\":\"\",\"push_pub\":\"/bitrix/pub/\",\"push_sub\":\"/bitrix/sub/\",\"push_subws\":\"/bitrix/subws/\",\"push_rest\":\"/bitrix/rest/\",\"nodejs_version\":\"not_installed\",\"nodejs_major_version\":\"not_installed\",\"push_server_version\":\"not_installed\",\"push_server_major_version\":\"not_installed\",\"nginx_push_module\":\"installed\",\"sphinx_version\":\"not_installed\",\"sphinx_type\":\"21\",\"mysql_version\":\"5.7.21\",\"mysql_mid_version\":\"7\",\"mysql_package\":\"Percona-Server-server\",\"mysql_service\":\"mysqld\",\"mysql_root_config\":\"/root/.my.cnf\",\"mysql_root_password\":\"set\",\"mysql_service_status\":\"active\",\"php_version\":\"not_installed\",\"php_union_version\":00,\"php_upgraded_versions\":[56,70,71,72,73,74],\"php_rollback_versions\":[],\"php_older_version\":0,\"php_mysql_ext\":\"\",\"bx_root_last_password_change\":\"Feb 28, 2018\",\"bx_last_password_change\":\"Feb 26, 2018\",\"firewalld_package\":\"installed\",\"firewalld_status\":\"not_running\",\"firewalld_bx_type\":\"not_installed\",\"firewalld_tolerance\":\"non_compatible\",\"iptables_status\":\"stateful\"}}", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 0} 

После нескольких часов работ и восстановлений состояния виртуальной машины из снэпшота, было принято решение отказаться от обновления окружения BitrixVM и развернуть отдельный сервер под управлением ОС Debian по общим стандартам с требуемым ПО. И выполнить переезд проектов на него. От себя хочу добавить, что данный вариант, при выполнении работ по обновлению BitrixVM, считаем оптимальным, а именно переезд на новый сервер, либо с уже установленной новой версией BitrixVM, на борту, или на новый сервер под управлением другого дистрибутива Linux.

После задача была закрыта и проект работал в штатном режиме. Однако, буквально через несколько месяцев перед нами вновь встала задача обновления PHP до версии 7.4 для BitrixVM, в этот раз с CRM Битрикс24 на борту. Ситуация усложнялась тем, что обновление необходимо было выполнить в течении нескольких дней, а сам сервер располагался физически в офисе заказчика, что означало для нас невозможность переезда на новую инфраструктуру в кратчайшие сроки.

Битрикс24 это CRM система, которая предполагает большой объем данных БД, что также усложняло переезд и сильно било по стоимости новой инфраструктуры. При этом проект, на котором необходимо было выполнить работы не предусматривал какого либо резервного контура.

Времени на детальное составление плана не было, первоначальным вариантом было выполнить обновление стандартными средствами Битрикс при этом на случай появления проблем, решить которые не удастся, использовать lvm snapshot для отката состояния сервера.

Также рассмотрен вариант разворачивания Docker контейнера c необходимой версией PHP7.4 и настроенный для работы с BitrixVM. Данный вариант показался для нас более выгодным, так как исключал все потенциальные проблемы, которые могли возникнуть при обновлении BitrixVM, а также предусматривал минимальный простой в работе проекта (в последствии простой был, однако он составил не более 5 минут, это то время, которое потребовалось для переключения Nginx для работы с Apache2 в контейнере).

Имея большой опыт работы с Docker мы не видели проблемы в разворачивании контейнера, также в отличии от BitrixVM, с Docker мы могли полностью контролировать процесс обновления, а в случае появления проблем изучать логи Apache в контейнере и сервисов установленных на сервере, которые более информативны, чем логи Ansible ролей виртуальной машины Битрикс. После небольших консультации внутри команды было принято решение развернуть контейнер. На сервере была установлена БитриксВМ 7.3.4, под управлением Centos7.4. Данные работы будут описаны в статье ниже. Я постарался максимально подробно описать проделанные нами шаги, для тех, кому это решение окажется полезным. Также в конце статьи будет приложена ссылка на github с конфигурацией контейнера.

Ход работ

Перед началом работ ставим пакеты docker-ce, docker-ce-cli, containerd.io для Centos7 согласно инструкции:

https://docs.docker.com/engine/install/centos/

После устанавливаем docker-compose (на момент публикации статьи актуальной версией является 1.29.2):

curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Подготавливаем docker-compose файл где описываем контейнер. Контейнер был собран но основании php:7.4-apache, в Dockerfile были включены все необходимые PHP модули. За основу виртуального хоста Apache был взят оригинальный файл BitrixVM, с небольшими правками, учитывающими работу в контейнере. В частности, вам придется указать AssignUserId в конфигурации виртуального хоста Apache, в виду отсутствия пользователя bitrix в контейнере. Добавлю, что apache2 в нашем случае работает с модулем mpm_prefork настройки для которого также прокинуты в контейнер.

Для корректной работы в docker-compose файле потребуется прокинуть в контейнер стандартные директории площадки для bitrix. В целом блок volumes в нашем варианте выглядит следующим образом:

  volumes:
      - ./volumes/var/log/apache2:/var/log/apache2
      - ./volumes/etc/apache2/conf.d/nxs-std.conf:/etc/apache2/conf.d/nxs-std.conf:ro
      - ./volumes/etc/apache2/sites-enabled:/etc/apache2/sites-enabled:ro
      - ./volumes/etc/php/conf.d/nxs-std.ini:/usr/local/etc/php/conf.d/nxs-std.ini:ro
      - ./volumes/etc/apache2/mods-enabled/status.conf:/etc/apache2/mods-enabled/status.conf:ro
      - ./volumes/etc/apache2/mods-enabled/mpm_prefork.conf:/etc/apache2/mods-enabled/mpm_prefork.conf:ro
      - /tmp/php_sessions/:/tmp/php_sessions/
      - /tmp/php_upload/:/tmp/php_upload/
      - /home/bitrix/:/home/bitrix/
      - /var/log/httpd:/var/log/httpd/

Логи apache2 для площадки были прокинуты на сервер в стандартную директорию, что также учтено в виртуальном хосте:

CustomLog /var/log/httpd/site_access.log combined
ErrorLog /var/log/httpd/site_error.log

Логи самого apache2 в контейнере расположены в /volumes/var/log/apache2.

Также потребуется внести ряд правок в php.ini и прокинуть файл в контейнер, эти шаги я опишу ниже, в рамках части про Битрикс оптимизацию.

Для решения проблем с правами необходимо добавить в описание контейнера в docker-compose строки:

cap_add:
      - SYS_NICE
      - DAC_READ_SEARCH

Для удобства указания общения контейнера с сервером присваиваем ему IP:

    networks:
      default:
        ipv4_address: 172.24.1.4

и настраиваем сеть:

networks:
  default:
    driver: bridge
    ipam:
      config:
        - subnet: 172.24.1.0/29
    driver_opts:
      com.docker.network.bridge.name: "br2-php74" 

После потребуется добавить подсеть docker контейнера в список разрешенных для фаервола, в нашем случае правила выглядят так:

-A POSTROUTING -s 172.24.1.0/29 -j MASQUERADE
-A INPUT -s 172.24.1.0/29 -j ACCEPT
-A FORWARD -s 172.24.1.0/29 -j ACCEPT
-A FORWARD -d 172.24.1.0/29 -j ACCEPT

Для корректной отправки почты, необходимо будет настроить почтовый сервер таким образом, что бы он мог принимать и ретранслировать почту отправленную из контейнера. В нашем случае для отправки почты использовался exim настроенный для работы в режиме smarthost, поэтому потребовалось добавить адрес контейнера (172.24.1.4) в следующие строки:

domainlist local_domains = @ : localhost : 172.24.1.4
hostlist   relay_from_hosts = localhost : 172.24.1.4

Битрикс оптимизация

После того как контейнер был готов запущен, перед переключением площадки необходимо было провести Битрикс оптимизацию, то есть устранить все ошибки в тестировании конфигурации. От себя добавлю, что до переноса в контейнер ошибок в тестировании конфигурации не было.

Для решения этих задач была создана отдельная тестовая площадка на основном сервере, в которую был помещен установочный скрипт Битрикс. Площадка развернута через стандартное меню Битрикс /root/menu.sh.

Для тестовой площадки настраиваем проксирование на уровне Nginx в контейнер, потребуется изменить переменную proxyserver в файлах виртуального хоста площадки.

set $proxyserver  "http://172.24.1.4:80";

После прокидываем созданный скриптом Битрикс виртуальный хост для apache2 в контейнер, при этом обязательно указываем UID пользователя Bitrix:

AssignUserId #600 #600

В нашем случае apache2 работает на стандартном 80 порту в контейнере, поэтому в виртуальном хосте указываем:

<VirtualHost *:80>

После меняем параметры подключения к БД в файлах dbconn.php и .settings.php c 127.0.0.1 на 172.24.1.1

$DBHost = "172.24.1.1"; - для dbconn.php
'host' => '172.24.1.1', - для .settings.php

После внесения всех этих изменений переходим в административную панель тестовой площадки, а далее заходим в Проверка системы > Тестирование конфигурации. В первую очередь всплывет ошибка работы с сокетами, для ее решения прописываем в docker-compose.yml параметр extra_hosts, указав внешний IP сервера и доменное имя площадки:

extra_hosts:
 - "site.ru:EXTERNAL_IP"

Перезапускаем контейнер. Также для корректной отправки почты, потребуется указать в настройках PHP sendmail_path:

sendmail_path = "msmtp -t -i --host=172.24.1.1 --port=25 -f info@site.ru"

Прохождение проверки отправки почты внутри административной панели Битрикс еще не означает, что ваше письмо будет доставлено, поэтому рекомендуем также выполнить самостоятельную отправку письма c помощью скриптов площадки, а после проверить наличие письма в почтовом ящике и логи почтового сервера.

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

mbstring.internal_encoding = UTF-8 
realpath_cache_size = 4096k
max_input_vars = 10000
allow_url_fopen = Off

Дополню, что в случае использования контейнера с Битрикс24 будет всплывать предупреждение вида:

Ошибка! Для гарантированной работы "1С-Битрикс24" необходимо его устанавливать на веб-окружении Битрикс, у вас используется собственное серверное окружение.

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

Также вы можете выполнить тестирование производительности конфигурации и анализ площадки с помощью сканера безопасности. В нашем случае цифры в тестировании конфигурации были практически идентичны как в случае с контейнером, так и без него.

После того, как оптимизация для тестовой площадки будет выполнена, возможно будет приступить к переключению основной площадки для работы в контейнере, при этом учесть все шаги, проделанные в рамках тестовой оптимизации ранее.

Заключение

Целью данной статьи не является пропаганда такого решения, оно будет полезно тем, кому жизненно важно обновление PHP на текущем этапе работы проекта, при этом нет возможности переехать на новую инфраструктуру, а также нет уверенности в том, что обновление Битрикс из бета репозиториев пройдет гладко.

BitrixVM является простым в установке решением, однако в случае администрирования кастомной конфигурации решение проблем и проведение каких-либо обновлений проходит сильно проще.

Для удобства выложили конфигурацию нашего контейнера на GitHub, вы всегда можете ознакомится с ней по мере необходимости. Там же расположен отредактированный виртуальный хост площадки, все вносимые в PHP и Apache2 настройки и docker-compose.yml.

https://github.com/morgeshtern/php_bitrix_docker

В заключении от себя хочется сказать, что в процессе администрирования мы видим больше минусов, чем плюсов в разворачивании BitrixVM в качестве окружения, в частности это связано со следующими пунктами:

  • Сложность внесения каких-либо настроек в систему и установки нового ПО. Запутанность файлов конфигураций ПО в BitrixVM, а также использование ansible-скриптов для управления сервером через меню с псевдографическим интерфейсом приводит к тому, что внесение даже самых элементарных настроек требует большого количества времени со стороны администраторов, которое уходит именно на то, чтобы понять где именно необходимо внести данные изменения, чтобы в дальнейшем они не были перезаписаны ansible-скриптами, а так же не имели негативного влияния на работу других элементов системы.

  • В BitrixVM абсолютно все площадки работают из-под одного пользователя - bitrix. Соответственно ни о какой изоляции и соответственно безопасности проектов не может быть и речи (т.е. если используя какие-либо уязвимости в коде одного сайта, его взломают, то это будет означать, то злоумышленник получит доступ сразу ко всем остальным). Иными словами BitrixVM может подойти только тогда, когда на сервере работает только одна площадка.

  • В случае возникновения каких-либо проблем на сервере, на анализ и устранения причин неисправности уходит намного больше времени, чем при разборе ситуаций на кастомной настройке. В виду плохо настроенной системы логирования.

  • Также как показывает наш опыт, интеграция со сторонними сервисами в случае с BitrixVM зачастую очень сложна или невозможна.

Из плюсов такого решения могу отметить то, что конфигурация BitrixVM проста в первоначальной настройке. Однако рекомендовать это решение, можно разве что для простых проектов.

Источник: https://habr.com/ru/company/nixys/blog/576116/

Интересные статьи

Интересные статьи

Появившиеся в 2006 году сервисы Google по работе с текстовыми документами (Google Docs) и таблицами (Google Sheets), дополненные 6 лет спустя возможностями работы с вирту...
Маркетплейс – это сервис от 1С-Битрикс, который позволяет разработчикам делиться своими решениями с широкой аудиторией, состоящей из клиентов и других разработчиков.
VUE.JS - это javascript фрэймворк, с версии 18.5 его добавили в ядро битрикса, поэтому можно его использовать из коробки.
Привет, Хабр. В этой статье я хочу рассказать о своем опыте создания учебной среды для экспериментов с микросервисами. При изучении каждого нового инструмента мне всегда хотелось его попробова...
Бизнес-смыслы появились в Битриксе в начале 2016 года, но мало кто понимает, как их правильно использовать для удобной настройки интернет-магазинов.