Это короткий how-to для реализации конфигурации php-сервиса, зависимого от окружения, в котором он запущен. Я буду рад, если кто-то подскажет более изящное решение или поправит в мелочах.
Основная идея
Запускать сервис, микросервисы и зависимые приложения в рамках одной экосистемы, конфигурируемой с помощью переменных окружения .Проблема
В этой статье слишком много раз повторяется «переменные окружения».Из коробки php-fpm игнорирует глобальные переменные окружения (getenv function), в то время как php cli их может получать.
Предыстория
Этот раздел можно пропустить, если вы уже работали с.env
В данный момент я работаю над проектом, написанном на ZF2. Для конфигурации проекта использовались конфиг-файлы для разных окружений . Это порождает большое количество дубликатов конфигурации в репозитории проекта примерно такого вида:
- session.global.php
- session.local.php.dist
- session.unittest.php.dist
- db.global.php
- db.local.php.dist
- db.unittest.php.dist
Итак, проект теперь учитывает окружение, но...
Пока разработка велась на рабочих машинках, проект читал.env файл и всё работало. Но когда я развернул тестовую среду, оказалось, что если задать взаправдашние системные переменные окружения, php-fpm их игнорирует. Различные рецепты из гугла и StackOverflow сводились к той или иной автоматизации использования двух известных способов:1. Передача переменных через nginx параметром fastcgi_param SOMEENV test;
2. Установкой переменных в формате env в конфигурации пула рабочих процессов php-fpm .
И первый, и второй вариант, удобны для каких-то особых ситуаций. Но если мыслить в парадигме «конфигурировать среду, а не приложение», то подобные способы оказываются куда труднее, чем например просто положить.env файл в папку с проектом. Но ведь оркестратор, CI-система или просто системный администратор не должен знать детали реализации проекта, это не изящно.
Предлагаемый способ решения
Скомбинировав различные рецепты из сети, я нащупал следующее рабочее решение.Тестировалось под Centos 7, PHP 5.6.14.
1. Открыть /etc/php.ini - Заменить variables_order = "GPCS" на variables_order = "EGPCS" # После этого PHP добавит в глобальное пространство переменные окружения # http://php.net/manual/ru/ini.core.php#ini.variables-order 2. Открыть /etc/php-fpm.d/www.conf, не путать с /etc/php-fpm.conf (в разных системах может быть в разном месте, это конфиг www-пула процессов для php-fpm. - Добавить (или заменить, если вдруг есть): clear_env = no # выключить очистку глобальных переменных для запускаемых воркеров 3. Установить необходимые переменные окружения в /etc/environment (стандартный синтаксис A=B) 4. ln -fs /etc/environment /etc/sysconfig/php-fpm # теперь конфиг переменных окружения сервиса php-fpm будет просто ссылкой на глобальный конфиг 5. systemctl daemon-reload && service php-fpm restart
Этот же подход с симлинком, в теории, применим и к другим сервисам.
Плюсы предложенного решения:
- Переменные, хранящиеся в /etc/environment, доступны разным приложениям. Можно вызвать echo $MYSQL_HOST в shell или getenv("MYSQL_HOST") в php.
- Переменные окружения, которые явно не заданы в /etc/environment, не попадут в php-fpm. Это позволяет с помощью оркестратора контролировать окружение извне изолированной системы, в которой запущен сервис.
Минусы:
- К сожалению, у php-fpm я не нашел работающей команды для reload по аналогии с nginx, так что в случае изменения /etc/environment, обязательно нужно делать systemctl daemon-reload && service php-fpm restart
.
Важно : если ваше приложение работает не в изолированной среде (сервер, виртуалка, контейнер), определение переменных окружения может непредсказуемо повлиять на соседние сервисы в системе из-за совпадений имён в глобальном пространстве.
Когда браузер запрашивает от веб-сервера документ, он также пересылает на сервер техническую информацию об определённых параметрах браузера и операционной системы. Веб-сервер в свою очередь одновременно с документом возвращает некоторые свои характеристики. Таким образом, браузер и веб-сервер обмениваются данными, которые называются переменные окружения. Эти переменные можно применять в своих целях и отображать их на веб-странице.
При использовании SSI общий синтаксис вывода определенной переменной окружения будет следующий.
Некоторые переменные с их описанием перечислены в табл. 1. Заметьте, что все имена пишутся заглавными символами. Хотя это условие и необязательно, именно такая форма записи является традиционной и устоявшейся.
Переменная | Описание |
---|---|
DOCUMENT_ROOT | Путь к корневой папке сайта. Для локального веб-сервера значение может принимать вид z:/home/сайт/www, а в других случаях зависит от операционной системы сервера и используемого программного обеспечения. |
GATEWAY_INTERFACE | Версия CGI (Common Gateway Interface, общий шлюзовый интерфейс). Значение обычно равно CGI/1.1 . |
HTTP_ACCEPT | Типы файлов, которые способен принять браузер. В качестве значения возвращается список поддерживаемых MIME-типов разделенных между собой запятой, например: text/html, application/xhtml+xml . |
HTTP_CONNECTION | Тип соединения браузера с веб-сервером. Так, значение keep-alive означает, что браузер поддерживает постоянное соединение с сервером. При этом в течение одного сеанса соединения разрешено делать несколько запросов. Повторного соединения в таком случае уже не происходит. |
HTTP_HOST | Доменное имя сайта. Обычно различают имена с префиксом www (www..ru). Переменная вернёт тот адрес сайта, который указан в адресной строке браузера. |
HTTP_REFERER | Адрес страницы, с которой пользователь перешел на данный сайт, он еще называется реферер. |
HTTP_USER_AGENT | Идентификатор используемого браузера и операционной системы. В качестве значения возвращается строка, содержащая ключевые слова. Например, следующая строка Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2 говорит, что пользователь использует браузер Firefox 6.0.2 под операционной системой Windows 7. |
QUERY_STRING | Запрос, который указан в адресной строке после вопросительного знака (?). Обычно пишется в форме «переменная=значение», где переменные разделяются между собой амперсандом (&).?id=5&slv=34 будет возвращено значение id=5&slv=34 . |
REMOTE_ADDR | IP-адрес посетителя сайта. |
REQUEST_METHOD | Метод отправки данных на сервер. По умолчанию применяется метод GET. |
REQUEST_URI | Адрес запрашиваемого документа. Отсчёт ведётся от корня сайта, т.е..html вернется значение 1.html . |
SERVER_ADDR | IP-адрес компьютера, на котором размещается сайт. |
SERVER_ADMIN | Адрес электронной почты администратора сайта. |
SERVER_NAME | Имя сервера. |
SERVER_PORT | Порт, по которому ожидается получение данных. |
SERVER_PROTOCOL | Протокол для получения и отправки данных. Значение обычно равно HTTP/1.1 . |
SERVER_SOFTWARE | Программное обеспечение установленное на сервере. Для веб-сервера Apache возвращается номер версии (Apache/2.2.4 ), а также версия PHP (PHP/5.3.3 ). |
В примере 1 показано использование переменных окружения для отображения на веб-странице требуемой информации.
Пример 1. Вывод значения переменной DOCUMENT_ROOT
Путь к корневой папке сайта:
В результате выполнения примера будет выведена следующая строка: Путь к корневой папке сайта: /home/сайт/www .
Значения переменных окружения можно посмотреть с помощью программы на PHP, используя функцию phpinfo(), как показано в примере 2.
Пример 2. Использование phpinfo()
В результате выполнения программы будет выведена таблица с разными параметрами, в том числе и переменными окружения в разделе «Apache Environment» (рис. 1).
Рис. 1. Apache Environment
Также можно написать программу на PHP, которая будет выводить все переменные окружения в виде таблицы (пример 3)..
Пример 3. Вывод переменных окружения
\n\n
$a | $b |
Непосредственно перед запуском сценария сервер передает ему некие переменные окружения с информацией. В определенных переменных содержаться некоторые заголовки, но не все (получить все заголовки нельзя). Далее я приведу список наиболее важных переменных окружения.
HTTP_ACCEPT
В этой переменной перечислены все MIME-типы данных , которые могут быть восприняты браузером. Строка */* означает, что браузер понимает любой тип.
HTTP_ACCEPT= image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, */*
HTTP_REFERER
Эта переменная представляет сведения о странице, с которой пользователь попал на данную. Эту переменную можно использовать, например, для отслеживания перемещения пользователя по вашему сайту, а затем просматривать наиболее популярные маршруты.
HTTP_REFERER= http://www.сайт/php/pril/
HTTP_COOKIE
В этой переменной хранятся все Cookies в URL-кодировке.
HTTP_COOKIE= hotlog=1; ZDEDebuggerPresent=php,phtml,php3; b=b; PHPSESSID=
HTTP_USER_AGENT
Идентифицирует браузер пользователя. Для установления типа браузера нужно проверить эту строку на наличие слов: если браузер - Internet Explorer, то будет присутствовать подстрока MSIE, а если в наличии лишь слово Mozilla, то это Netscape.
Например:
HTTP_USER_AGENT= Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MyIE2; Maxthon)
HTTP_HOST
Содержит доменное имя Web-сервера, на котором запустился сценарий. Эту переменную достаточно удобно использовать, например, для генерации полного пути, который требуется в заголовке Location, чтобы не привязываться к конкретному серверу.
HTTP_HOST= www.сайт
HTTP_FROM
Адрес электронной почты пользователя, направившего запрос.
SERVER_NAME
Доменное имя или IP-адрес сервера.
SERVER_NAME= www.сайт
SERVER_SOFTWARE
Имя и версия программы-сервера, отвечающей на запрос клиента.
SERVER_PORT
Эта переменная содержит порт сервера, к которому обратился браузер пользователя. Обычно это 80. Переменная так-же может применяться для формирования параметра заголовка Location.
SERVER_PORT= 80
SERVER_PROTOCOL
Переменная содержит имя и версию информационного протокола, который был использован для запроса.
SERVER_PROTOCOL= HTTP/1.1
REMOTE_ADDR
Эта переменная содержит IP-адрес (или доменное имя) узла пользователя, на котором был запущен браузер.
REMOTE_PORT
Порт, который закрепляется за браузером пользователя для получения ответа сервера.
REMOTE_USER
Идентификационное имя пользователя, посылающего запрос.
SCRIPT_NAME
Содержит имя файла, содержащего данный сценарий. Эту переменную удобно использовать при формировании заголовка Location при переадресации на себя (self-redirect), а также для подставления значения атрибута action тега
Антивирус Bitdefender: эффективный защитник Без вопросов
Значение слова неудачный
Обзор Samsung Galaxy A7 (2017): не боится воды и экономии Стоит ли покупать samsung a7
Делаем бэкап прошивки на андроиде
Как настроить файл подкачки?