Background
我正在尝试使用 Wercker 来运行我的 PHP 应用程序测试。Wercker 使用 Docker 容器来设置一个测试环境来执行测试。它使用环境变量来公开任何连接服务(如MySQL和Elasticsearch)的连接参数。例 MYSQL_PORT_3306_TCP_ADDR = 127.0.1.1
我的核心Docker容器正在运行Ubuntu 14.04,容器上已经安装了PHP和Apache。
问题
通过 Apache 运行时,我似乎无法通过 php $_SERVER 或 $_ENV 访问环境变量。如果我通过 CLI php ./db_connect.php
运行脚本,或者如果我使用服务器php -S localhost:8000
中的内置运行 PHP,它可以正常工作。但是,如果我尝试通过 Apache 虚拟主机访问页面,则环境变量不可用。
进展
我已经使用用于允许环境变量"我认为"的模组设置了 Apache
。sudo a2enmod env
sudo service apache2 restart
我正在尝试访问脚本中的环境变量。
$database_host = $_SERVER["MYSQL_PORT_3306_TCP_ADDR"];
$database_username = $_SERVER["MYSQL_ENV_MYSQL_USER"];
$database_password = $_SERVER["MYSQL_ENV_MYSQL_PASSWORD"];
$database_name = $_SERVER["MYSQL_ENV_MYSQL_DATABASE"];
$elasticsearch_host = $_SERVER["ELASTICSEARCH_PORT_9300_TCP_ADDR"];
我可以在我的 .htaccess 中添加新变量,只是没有得到所有系统环境变量。
SetEnv TEST_VAR test
我已经阅读了这个问题如何在运行CLI和Apache2Handler时将系统环境变量放入PHP?但我不确定它的建议是什么。
问题
如何将系统环境变量公开给 Apache 和 PHP?
如果你使用的是 php 官方 Docker 镜像,你必须显式地将环境变量从 Apache 传递给 PHP。你可以做这样的事情:
在您的 Dockerfile 中:
FROM php:7.2-apache
RUN echo 'SetEnv MYSQL_USER ${MYSQL_USER}' > /etc/apache2/conf-enabled/environment.conf
environment.conf
是一个任意名称,但它应该放在 /etc/apache2/conf-enabled/
中。
在 docker-compose.yml 中:
version: '2'
services:
yourservice:
build: ./yourimage
image: yourimage
ports:
- 8080:80
volumes:
- ../html:/var/www/html
environment:
MYSQL_USER: foo
在您的 PHP 脚本中:
echo getenv('MYSQL_USER');
这是解决方案:
Docker会将这些传递给apache,但您必须配置apache以使它们可用于PHP。
在本地 .env 文件中设置值
MYSQL_PORT_3306_TCP_ADDR=1234
MYSQL_ENV_MYSQL_USER=development
MYSQL_ENV_MYSQL_PASSWORD=password
然后将这些作为环境参数添加到 docker-compose.yml 文件中
version: 2
services:
web:
build: php:5.6-apache
environment:
MYSQL_PORT_3306_TCP_ADDR:${MYSQL_PORT_3306_TCP_ADDR}
MYSQL_ENV_MYSQL_USER: ${MYSQL_ENV_MYSQL_USER}
MYSQL_ENV_MYSQL_PASSWORD: ${MYSQL_ENV_MYSQL_PASSWORD}
然后将它们传递给 PHP,将它们设置为虚拟主机配置中的环境参数
<VirtualHost *:80>
ServerName some-project
ServerAdmin webmaster@localhost
DocumentRoot /var/www/some-project
# Set apache environment variables
SetEnv MYSQL_PORT_3306_TCP_ADDR ${MYSQL_PORT_3306_TCP_ADDR}
SetEnv MYSQL_ENV_MYSQL_USER ${MYSQL_ENV_MYSQL_USER}
SetEnv MYSQL_ENV_MYSQL_PASSWORD ${MYSQL_ENV_MYSQL_PASSWORD}
</VirtualHost>
这些现在可以通过 $_SERVER 超级全局数组在 PHP 中访问。
<?php
echo $_SERVER['MYSQL_ENV_MYSQL_USER'];
如果你使用的是php-FPM,你可以通过像/path/to/php/fpm/pool.d/www.conf
这样的文件中的ini设置将env vars从操作系统传递到PHP-FPM clear_env
:
clear_env = no
它适用于通过 docker-compose.yml 设置environment
变量,如下所示:
version: "..."
services:
php-fpm:
image: php:7-fpm
environment:
MY_VAR: my-value
重要提示:当然,风险在于您的 PHP-FPM 将可以访问所有操作系统环境变量。如果传递所有 vars 是一个问题,您也可以通过 www.conf
或其他 php ini 配置文件仅传递特定的 var:
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
env[MY_VAR] = $MY_VAR
使用 docker-compose 你可以通过 php 的 $_ENV
变量检索使用 docker-compose.yml 文件的environment
选项设置的操作系统的环境变量。
version: 2
services:
web:
build: php:5.6-apache
environment:
MYSQL_USER: "user"
MYSQL_PASSWORD: "passwd"
应该给你
$_ENV['MYSQL_USER'] = user
$_ENV['MYSQL_PASSWORD'] = passwd
我不确定 Wercker 如何将环境变量映射到容器,但我认为这个悬而未决的问题可能会有所帮助https://github.com/wercker/wercker/issues/63
您可以使用php命令检查获取环境,如下所示
php -r "echo getenv('MYSQL_USER');"