php: Environment variables ignored by php-fpm

If you use the php-fpm variant, environment variables (e.g. for linked docker hosts) are not available in your $_ENV var in your PHP scripts. This is a problem as usually docker containers are configured via environment variables (following the 12 factor principles). While this is rather a PHP problem, I still think that the official php-fpm image should provide a workaround for this, as otherwhise it’s pretty much useless.

For php-fpm all environment variables have to be listed in the php-fpm.conf like:

[www]
env[MY_ENV_VAR_1] = 'value1'
env[MY_ENV_VAR_2] = 'value2'

So I suggest to create a wrapper script to first add all variables from env to the configuration, before actually starting php.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 16
  • Comments: 34 (12 by maintainers)

Commits related to this issue

Most upvoted comments

If you’re going to re-expose the whole environment, clear_env = no would be simpler.

👍 for clear_env = Yes by default

oops that was a mistake 😕 I meant 👍 for clear_env = no by default… as for the reason, it’s because I need to add it manually in each of my php-fpm containers, I guess a lot of people have to do the same or worst are manually adding each need env var in php-fpm conf as you did at first. it’s not that easy to find information about clear_env when you search for “php-fpm env var” on google

Here’s a workaround that does the job for me. It would be great if we could include that in the php-fpm image:

FROM php:5.6.6-fpm

# Allow to include custom php-fpm config, e.g. to set environment variables
RUN echo 'include=/usr/local/etc/conf.d/*' >> /usr/local/etc/php-fpm.conf \
    && mkdir /usr/local/etc/conf.d/

COPY run-php-fpm /usr/local/bin/

CMD ["run-php-fpm"]

run-php-fpm:

#!/bin/bash

env | sed "s/\(.*\)=\(.*\)/env[\1]='\2'/" > /usr/local/etc/conf.d/env.conf

php-fpm

@deiucanta

This is strange - I’ve uncommented clear_env = no but I can’t access ENV vars inside PHP.

In the case you were starting php-fpm not in a container but with systemd you need to said it where to get environment variables. For example set in /lib/systemd/system/php7.2-fpm.service:

EnvironmentFile=/etc/environment

ENV[*] from fpm config can be reached as $_SERVER[*] in PHP.

This is the same default that is in debian when installing the php5-fpm package, as well as the default in php (php.net). There is no corresponding setting for non-fpm php.

$ cat /etc/php5/fpm/pool.d/www.conf
...
; Clear environment in FPM workers
; Prevents arbitrary environment variables from reaching FPM worker processes
; by clearing the environment in workers before env vars specified in this
; pool configuration are added.
; Setting to "no" will make all environment variables available to PHP code
; via getenv(), $_ENV and $_SERVER.
; Default Value: yes
;clear_env = no

That said, since php is the only process in the container, I think it would be sane to change from upstream’s default and add clear_env = no, since then php will have access to things like linked sql address and port variables.

This is strange - I’ve uncommented clear_env = no but I can’t access ENV vars inside PHP.

For those who still don’t have access to $_ENV, this php.ini setting is (now) important (in e.g. php:8.0-fpm-alpine).

from php.ini-production:

; This directive determines which super global arrays are registered when PHP
; starts up. G,P,C,E & S are abbreviations for the following respective super
; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
; paid for the registration of these arrays and because ENV is not as commonly
; used as the others, ENV is not recommended on productions servers. You
; can still get access to the environment variables through getenv() should you
; need to.
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
variables_order = "GPCS"

From http://php.net/manual/en/install.fpm.configuration.php:

clear_env boolean Clear environment in FPM workers. Prevents arbitrary environment variables from reaching FPM worker processes by clearing the environment in workers before env vars specified in this pool configuration are added. Since PHP 5.4.27. Default value: Yes.

You’d put it in your php-fpm.conf or a file included from it.

FWIW, I don’t think the php:fpm image should be changed to act as you’ve requested, but I do think the environment variable issue should be documented.

For those of us on CentOS 7 who can’t use clear_env = no (php-fpm is just a tiny bit too old), mikehaertl’s comment regarding the workaround with sed is a lifesaver.

sed -i "s|;*clear_env\s*=\s*yes|clear_env = no|g" /etc/php5/php-fpm.conf

clear_env = no works

Hi!

just googled this issue and it looks like a good place for my 5 cents.it’s not according this concrete docker image, but a caution to a docker image writers:

many docker images are built so that all passwords are configured during the first run. This means you specify passwords that are available as environment variables in a running container during all docker container life cycle. For containers like the ones with PHP or any other server-side scripting language inside which have access to environment variables this looks like a security issue: anyone who can eval some code on the server may read environment variables (if allowed, actually. But tuning this off may be forgotten, or be changed in a running container without recalling the side effects or by another person who tries to solve some other issue).

So personally I decided that it should be always separated. I build my own containers with all sensitive data being provided during the build step. Then I run it without providing any passwords. Yes, not very share-friendly and not that much convenient, but it works.

Please let me know if I’m missing something, or if you feel like I’m doing this completely wrong. Thanks!