【问题标题】:Expose environment variables to Apache and PHP向 Apache 和 PHP 公开环境变量
【发布时间】:2016-06-27 10:53:25
【问题描述】:

背景

我正在尝试使用 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 虚拟主机访问页面,则环境变量不可用。

进展

我已经使用用于允许环境变量“我认为”的 mod 设置 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

我已经阅读了这个问题How to get system environment variables into PHP while running CLI & Apache2Handler?,但我不确定它的建议是什么。

问题

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

【问题讨论】:

  • 你试过$_ENV['MYSQL_PORT_3306_TCP_ADDR'] 吗?请注意,不推荐使用链接的环境变量,并且不再为 docker 1.9 及更高版本中的新自定义网络设置。更好的方法是使用链接的容器的名称进行连接,例如http://mysql 连接到“mysql”容器。环境变量并没有添加太多,因为你需要nameport号来获取ip地址,所以使用容器的名称无论如何更容易.
  • 是的,已尝试从 $_ENV 和 $HTTP_ENV_VARS 访问环境变量以确保安全。容器链接解决方案可能有效,唯一的问题是容器公开了附加信息,例如它在设置 $_SERVER["MYSQL_ENV_MYSQL_DATABASE"] 和我还需要的随机 root 密码 $_SERVER['MYSQL_ENV_MYSQL_ROOT_PASSWORD'] 上创建的数据库表。

标签: php apache ubuntu docker


【解决方案1】:

使用 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

【讨论】:

  • 确实应该工作,但根据我的经验和问题,似乎“docker + apache + php”不一定通过那些环境变量通过 php。 IDK 在什么情况下这是一个问题,但我在不包含 wercker 的环境中看到了这一点 - 所以这是关于 apache 设置,或者 docker 如何将变量传递给 apache。
  • 仅在 docker-compose.yml 中设置 environment 不足以将变量传递给 PHP。 environment 中列出的变量将在 Apache 配置文件中可用,格式为 ${MYSQL_USER},但您还必须在 Apache 配置中使用 SetEnv 指令将变量传递给 PHP。有关完整示例,请参阅我的答案。
【解决方案2】:

解决方法如下:

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'];

【讨论】:

    【解决方案3】:

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

    php -r "echo getenv('MYSQL_USER');"
    

    【讨论】:

      【解决方案4】:

      如果您使用php official Docker image,则必须将环境变量从 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');
      

      【讨论】:

      • 最佳答案。无需过多地弄乱配置文件。非常简单的解决方案,同时将所有控制权保留在 Dockerfile/docker-compose 中。
      • 像魅力一样工作。这绝对是要走的路!
      • 不错的解决方案!一项建议是使用&gt;&gt; 而不是&gt;,以免丢失environment.conf 文件的先前内容(如果有)。
      【解决方案5】:

      如果您使用的是 php-fpm,您可以通过 clear_env ini 设置在类似 /path/to/php/fpm/pool.d/www.conf 的文件中将环境变量从操作系统传递到 PHP-FPM:

      clear_env = no
      

      它适用于通过 docker-compose.yml 设置的environment vars,如下所示:

      version: "..."
      
      services:
          php-fpm:
              image: php:7-fpm
              environment:
                  MY_VAR: my-value
      

      重要提示:当然,风险在于您的 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
      

      【讨论】:

        猜你喜欢
        • 2011-02-25
        • 1970-01-01
        • 2011-09-20
        • 2017-08-26
        • 2013-03-03
        • 1970-01-01
        • 2019-02-04
        • 2023-03-10
        • 2015-04-21
        相关资源
        最近更新 更多