在与–link链接的Docker容器中访问环境variables

我正在为Docker容器中的应用程序设置开发环境,现在我有这些容器:

myapp-data - Holds application source code and log files myapp-phpfpm - Runs the php5-fpm process for Nginx myapp-nginx - Runs the Nginx web server that serves the application 

这个设置很好用,我真的很高兴。 但是我的应用程序需要一个MySQL数据库来连接,所以我使用官方的MySQL镜像 ,像这样运行它:

 sudo docker run --name myapp-mysql -e "MYSQL_ROOT_PASSWORD=iamroot" -e "MYSQL_USER=redacted" -e "MYSQL_PASSWORD=redacted" -e "MYSQL_DATABASE=redacted" -d mysql 

这也很好。 但是我的myapp-phpfpm容器需要链接到myapp-mysql容器,以便将MySQL的连接细节公开给我的应用程序。 所以我重新启动我的myapp-phpfpm容器:

 sudo docker run --privileged=true --name myapp-phpfpm --volumes-from myapp-data --link myapp-mysql:mysql -d readr/phpfpm 

所以现在我的myapp-phpfpm容器被链接到我的myapp-mysql容器,所以我应该能够访问我的PHP应用程序中的数据库。

问题是我不能。 PHP应用程序中不存在环境variables。 如果我做:

 die(var_dump(`printenv`)); 

我没有得到MySQL环境variables。 要尝试debugging,我做了一个whoami来找出哪些用户PHP正在运行,这是www-data 。 然后,我在容器中创build了一个bash进程,使用su www-data成为www-data用户,并在那里做了printenv 。 果然,MySQL环境variables确实存在于那里:

 MYSQL_PORT_3306_TCP_PORT=3306 MYSQL_PORT_3306_TCP=tcp://172.17.1.118:3306 MYSQL_ENV_MYSQL_ROOT_PASSWORD=iamroot ... etc ... 

那么,我如何才能访问Docker公开的关于PHP中的myapp-mysql容器的环境variables呢?

我通过创build一个自定义的start.sh脚本解决了这个问题,然后从我的Dockerfile

 #!/bin/sh # Function to update the fpm configuration to make the service environment variables available function setEnvironmentVariable() { if [ -z "$2" ]; then echo "Environment variable '$1' not set." return fi # Check whether variable already exists if grep -q $1 /etc/php5/fpm/pool.d/www.conf; then # Reset variable sed -i "s/^env\[$1.*/env[$1] = $2/g" /etc/php5/fpm/pool.d/www.conf else # Add variable echo "env[$1] = $2" >> /etc/php5/fpm/pool.d/www.conf fi } # Grep for variables that look like MySQL (MYSQL) for _curVar in `env | grep MYSQL | awk -F = '{print $1}'`;do # awk has split them by the equals sign # Pass the name and value to our function setEnvironmentVariable ${_curVar} ${!_curVar} done # start php-fpm exec /usr/sbin/php5-fpm 

然后将环境variables添加到PHP5-FPMconfiguration中,以便可以从PHP脚本中访问它们。

php-fpm默认清除所有的环境variables,/ /etc/php5/fpm/pool.d/www.conf /php5/fpm/pool.d/ /etc/php5/fpm/pool.d/www.conf

 ; Setting to "no" will make all environment variables available to PHP code ; via getenv(), $_ENV and $_SERVER. ; Default Value: yes ;clear_env = no 

你可以通过在Dockerfile取消注释来解决这个Dockerfile

 RUN sed -i -e "s/;clear_env\s*=\s*no/clear_env = no/g" /etc/php5/fpm/pool.d/www.conf 

我build议使用类似fig的东西,并在启动时将env vars传递给两个容器。 如果你真的想要你可以docker inspect从任何其他容器的任何容器,如果你绑定docker套接字,然后做这样的事情:

 docker inspect -f {{.Config.Env}} myapp-mysql 

这个问题可能不是环境variables – 可能是你的PHP安装。

TL;在Apache和PHP下运行应用程序时可访问的DR环境variables可能在您使用nginx或lighttpd和fastcgi时不可用。

更长的版本

这是我理解的方式(这可能是错误的或不完整的,因为我的经验非常有限)。 因为PHP并不是作为nChart和FastCGI下的浏览器的一部分运行的,所以它不能访问启动浏览器的shell,因此无法访问该shell中的环境variables。

解决scheme是声明你感兴趣的variables作为configuration的一部分。 这个答案很简洁,但是它包含了这个问题的基本答案。