PHP: PHP-FPM игнорирует переменные — решения

Автор: | 02/13/2020
 

Имеется PHP приложение, которое для подключения к серверу баз данных использует дефолтные данные из файла /app/.env и переменные окружения.

Проблема заключается в том, что приложение не видит переменную $TEST_VAR, хотя в шаблоне Kubernetes пода она задана:

...
      containers:
      - name: application-dev-web
        image: bttrm-application:119
...
        - name: TEST_VAR
          valueFrom:
            secretKeyRef:
              name: bttrm-app-secret
              key: test_var
...

Значение определяется в секретах:

apiVersion: v1
kind: Secret
metadata:
  name: bttrm-app-secret
  namespace: application-dev-ns
type: Opaque
data:
  test_var: dGVzdF92YWwK

В поде переменная доступна, и значение можно получить, если в контейнере выполнить env:

kubectl -n application-dev-ns exec -ti application-dev-deploy-54c7666b99-frntf -c application-dev-web env | grep DB_
DB_PASSWORD=password

Однако, если создать файл с phpinfo() — в блоке Environment будуттолкьо две переменные, $USER и $HOME:

kubectl -n application-dev-ns exec -ti application-dev-deploy-66896585fc-622nh curl localhost:8080/info.php | grep -A 5 Environment
<h2>Environment</h2>
<table>
<tr class="h"><th>Variable</th><th>Value</th></tr>
<tr><td class="e">USER </td><td class="v">nobody </td></tr>
<tr><td class="e">HOME </td><td class="v">/ </td></tr>
</table>

Решение #1: env[TEST_VAR]

Первый вариант решения — добавить в конфиг FPM-пула строку:

...
env[TEST_VAR] = $TEST_VAR

Деплоим, проверяем:

kubectl -n application-dev-ns exec -ti application-dev-deploy-8458fb96bb-6x4xk curl localhost:8080/info.php | grep -A 6 Environment
<h2>Environment</h2>
<table>
<tr class="h"><th>Variable</th><th>Value</th></tr>
<tr><td class="e">TEST_VAR </td><td class="v">test_val
</td></tr>
<tr><td class="e">USER </td><td class="v">nobody </td></tr>
<tr><td class="e">HOME </td><td class="v">/ </td></tr>

Работает, но делать так каждой переменной, если их много — так себе затея, поэтому — есть друой вариант.

Решение #2: clear_env = no

Другой вариант — задать в настройках FPM параметр clear_env со значением no.

Обновляем настройки /etc/php7/php-fpm.d/www.conf:

...
    ;env[DB_PASSWORD] = $DB_PASSWORD
    clear_env = no

Деплоим, проверяем:

kubectl -n application-dev-ns exec -ti application-dev-deploy-c56fd488b-ld4hk curl localhost:8080/info.php | grep -A 6 Environment
<h2>Environment</h2>
<table>
<tr class="h"><th>Variable</th><th>Value</th></tr>
<tr><td class="e">KUBERNETES_PORT_443_TCP </td><td class="v">tcp://172.20.0.1:443 </td></tr>
<tr><td class="e">APPLICATION_DEV_SERVICE_PORT_80_TCP </td><td class="v">tcp://172.20.57.152:80 </td></tr>
<tr><td class="e">APPLICATION_DEV_SERVICE_SERVICE_PORT </td><td class="v">80 </td></tr>
<tr><td class="e">SUPERVISOR_GROUP_NAME </td><td class="v">php-fpm </td></tr>

Теперь в контейнере видим вообще все переменные, доступные поду.

Готово.

(не)Решение #3: variables_order в php.ini

У PHP имеется параметр, отвечающий за порядок передачи переменных, см. документацию:

variables_order string

Sets the order of the EGPCS (Environment, Get, Post, Cookie, and Server) variable parsing. For example, if variables_order is set to «SP» then PHP will create the superglobals $_SERVER and $_POST, but not create $_ENV$_GET, and $_COOKIE. Setting to «» means no superglobals will be set.

Проверяем текущее значение:

bash-5.0$ cat /etc/php7/php.ini | grep variables_order
; variables_order
variables_order = "GPCS"

Было предположение, что проблема возникла из-за отсутствия E (Environment) — но variables_order = "EGPCS" не помогло.