向Apache和PHP公开环境变量 背景

向Apache和PHP公开环境变量 背景,php,apache,ubuntu,docker,Php,Apache,Ubuntu,Docker,我正在尝试使用来运行PHP应用程序的测试。Wercker使用Docker容器来设置测试环境,以便在中执行测试。它使用环境变量公开任何连接服务(如MySQL和Elasticsearch)的连接参数。示例MYSQL\u PORT\u 3306\u TCP\u ADDR=127.0.1.1 我的核心Docker容器正在运行Ubuntu14.04,容器上已经安装了PHP和Apache 问题 在通过Apache运行时,我似乎无法通过php$\u服务器或$\u ENV访问环境变量。如果我通过CLIphp./

我正在尝试使用来运行PHP应用程序的测试。Wercker使用Docker容器来设置测试环境,以便在中执行测试。它使用环境变量公开任何连接服务(如MySQL和Elasticsearch)的连接参数。示例MYSQL\u PORT\u 3306\u TCP\u ADDR=127.0.1.1

我的核心Docker容器正在运行Ubuntu14.04,容器上已经安装了PHP和Apache

问题 在通过Apache运行时,我似乎无法通过php$\u服务器或$\u ENV访问环境变量。如果我通过CLI
php./db_connect.php运行脚本,或者如果我使用其内置服务器
php-S localhost:8000
运行php,那么它工作正常。但是,如果我尝试通过Apache虚拟主机访问页面,则环境变量不可用

进展 我已经用mod设置了Apache,用于允许环境变量“我认为”

我正在尝试访问脚本中的环境变量

$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
我读过这个问题,但我不确定它建议做什么

问题:
如何向Apache和PHP公开系统环境变量?

使用docker compose,您可以通过PHP的
$\u ENV
变量检索操作系统的环境变量集,该环境变量集使用docker-compose.yml文件的
环境
选项设置

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如何将环境变量映射到容器,但我认为有一个开放的问题可能会有所帮助
解决方案如下:

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>

服务器命名某个项目
服务器管理员webmaster@localhost
DocumentRoot/var/www/some项目
#设置apache环境变量
SetEnv MYSQL\u PORT\u 3306\u TCP\u ADDR${MYSQL\u PORT\u 3306\u TCP\u ADDR}
SetEnv MYSQL_ENV_MYSQL_USER${MYSQL_ENV_MYSQL_USER}
SetEnv MYSQL_ENV_MYSQL_PASSWORD${MYSQL_ENV_MYSQL_PASSWORD}
现在可以通过$\u服务器超级全局数组在PHP中访问这些文件

<?php
    echo $_SERVER['MYSQL_ENV_MYSQL_USER'];

您可以使用下面的php命令检查get env

php -r "echo getenv('MYSQL_USER');"
如果使用,则必须显式地将环境变量从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');

如果您使用的是php-fpm,则可以通过
clear_-env
ini设置将env-vars从操作系统传递到php-fpm,设置文件类似于
/path/to/php/fpm/pool.d/www.conf

clear_env = no
它与通过docker compose.yml设置的
环境
变量一起工作,如下所示:

版本:“…”
服务:
php fpm:
图片:php:7-fpm
环境:
我的价值
重要提示:当然,风险在于您的PHP-FPM将访问所有操作系统环境变量。如果传递所有变量是一个问题,您还可以通过
www.conf
或其他php ini配置文件仅传递特定的变量:

; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
env[MY_VAR] = $MY_VAR

您是否尝试过
$\u ENV['MYSQL\u PORT\u 3306\u TCP\u ADDR']
?请注意,链接的环境变量已弃用,不再为docker 1.9及更高版本中的新自定义网络设置。更好的方法是使用链接的容器的名称进行连接,例如
http://mysql
连接到“mysql”容器。环境变量没有添加太多内容,因为您需要名称和端口号来获取ip地址,因此使用容器名称更容易。是的,为了确保安全,我们尝试从$\u ENV和$HTTP\u ENV\u VARS访问环境变量。容器链接解决方案可能会起作用,唯一的问题是容器会暴露额外的信息,比如它在setup$\u SERVER[“MYSQL\u ENV\u MYSQL\u database”]上创建的数据库表,以及我也需要的随机根密码$\u SERVER['MYSQL\u ENV\u MYSQL\u root\u password'。事实上这是应该起作用的,但根据我的经验,问题是,“docker+apache+php”似乎不一定要将这些环境变量传递给php。IDK在什么情况下这是一个问题,但我在一个不包括wercker的环境中看到了这一点,所以这是关于apache设置,或者docker如何将变量传递给apache。仅在docker-compose.yml中设置
environment
不足以将变量传递给PHP。
environment
中列出的变量将以${MYSQL\u USER}的形式出现在Apache配置文件中,但您还必须在Apache配置中使用SetEnv指令将变量向下传递给PHP。请参阅我的答案以获取完整的示例。最佳答案。不需要过多地处理配置文件。非常简单的解决方案,同时将所有控件保留在Dockerfile/docker-compose.com中,效果非常好。这绝对是一条路!
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
env[MY_VAR] = $MY_VAR