Expose environment variables to Apache and PHP

Viewed 15051

Background

I'm trying to use Wercker to run my test for a PHP application. Wercker uses Docker containers to setup a test environment to execute tests in. It uses Environment Variables to expose the connection params for any connected services like MySQL and Elasticsearch. Example MYSQL_PORT_3306_TCP_ADDR = 127.0.1.1

My core Docker containers is running Ubuntu 14.04 with PHP and Apache already installed on the container.

Problem

I can't seem to access the Environment Variables via php $_SERVER or $_ENV when running via Apache. It works fine if I run the script via CLI php ./db_connect.php or if I run PHP using its build in server php -S localhost:8000. However If I try and access a page via the Apache virtual host, the Environment Variables are not available.

Progress

I have setup Apache with the mod used to allow environmental variables "I think"

sudo a2enmod env
sudo service apache2 restart

I'm trying to access the Environment Variables in my script.

$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"];

I can add new variables in my .htaccess, I just don't get all the system environmental variables.

SetEnv TEST_VAR test

I have read this question How to get system environment variables into PHP while running CLI & Apache2Handler? but i'm not sure what its suggesting to do.

Question

How do I expose System Environment Variables to Apache and PHP?

5 Answers

If you are using php official Docker image you have to explicitly pass environment variables from Apache to PHP. You can do something like this:

In your Dockerfile:

FROM php:7.2-apache
RUN echo 'SetEnv MYSQL_USER ${MYSQL_USER}' > /etc/apache2/conf-enabled/environment.conf

environment.conf is an arbitrary name, but it should be placed in /etc/apache2/conf-enabled/.

In docker-compose.yml:

version: '2'
services:
    yourservice:
        build: ./yourimage
        image: yourimage
        ports:
            - 8080:80
        volumes:
            - ../html:/var/www/html
        environment:
            MYSQL_USER: foo

In your PHP script:

echo getenv('MYSQL_USER');

Here is the solution:

Docker will pass these to apache but you have to configure apache to make them available to PHP.

Setup the values in your local .env file

MYSQL_PORT_3306_TCP_ADDR=1234
MYSQL_ENV_MYSQL_USER=development
MYSQL_ENV_MYSQL_PASSWORD=password    

Then add these as environment params in the docker-compose.yml file

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}

Then to pass these to PHP set these as environment params in your Virtual Host config

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

These will now be available to access in PHP via the $_SERVER super global array.

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

if you're using php-fpm, you can pass env vars from OS to PHP-FPM through clear_env ini setting in a file like /path/to/php/fpm/pool.d/www.conf:

clear_env = no

it works with environment vars set via docker-compose.yml as below:

version: "..."

services:
    php-fpm:
        image: php:7-fpm
        environment:
            MY_VAR: my-value

IMPORTANT: Of course, the risk is that your PHP-FPM will get access to all OS env vars. If passing all vars is a problem, you can also pass only specific vars via www.conf or another php ini config file:

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

you can check get env with php command like below

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