6

Trying to do the following: Propagate environment values from .env file to php file environment values.

Set MYSQL variables in .env file.

#cat .env
MYSQL_ROOT_PASSWORD=RootPassword
MYSQL_USER=gnf_user
MYSQL_PASSWORD=UserPassword
MYSQL_DATABASE=gnf_noah
MYSQL_HOST=db

I would like that to propagate to my container. So I do:

#cat docker-compose.yml
version: "3.2"
services:
 www:
  build: . #Include Dockerfile in current directory
  ports:
  - "30001:80"
  - "30443:443"
  expose:
  - "80"
  - "443"
  volumes:
  - "var:/var/www/html/var/"
  environment:
   MYSQL_HOST: ${MYSQL_HOST}
   MYSQL_DATABASE: ${MYSQL_DATABASE}
   MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
   MYSQL_USER: ${MYSQL_USER}
   MYSQL_PASSWORD: ${MYSQL_PASSWORD}
  restart: always
  networks:
  - frontend
  - backend
  links:
  - db:db
# shortend for readability ;-)

Now, trying in my container to grab those values:

$db_host = getenv('MYSQL_HOST', true) ?: getenv('MYSQL_HOST');
$db_name = getenv('MYSQL_DATABASE', true) ?: getenv('MYSQL_DATABASE');
$db_user = getenv('MYSQL_USER', true) ?: getenv('MYSQL_USER');
$db_pwd  = getenv('MYSQL_PASSWORD', true) ?: getenv('MYSQL_PASSWORD');

Gives empty values.

Am I on the totally wrong page here.. or do I need a script to set those values on build time eg. in /docker-entrypoint-init.d" or something like that?

(EDIT) Files used:

drwxr-xr-x  2 root root  4096 Aug 16 18:54 conf
-rw-r--r--  1 root root  1406 Aug 17 17:17 docker-compose.yaml
-rw-r--r--  1 root root   992 Aug 17 19:31 Dockerfile
drwxr-xr-x  2 root root  4096 Aug 17 14:45 dump
-rw-r--r--  1 root root   125 Aug 17 07:06 .env
-rw-r--r--  1 root root 55799 Aug  6 20:10 install-php-extensions
drwxr-xr-x  2 root root  4096 Aug 13 08:36 mysql
drwxrwxr-x 25 root 1005  4096 Aug 18 05:40 www
osomanden
  • 599
  • 1
  • 10
  • 26

2 Answers2

7

Try using env_file in the compose file to reference your .env.

Here is a minimal example:

.
├── docker-compose.yml
├── Dockerfile
├── .env
└── index.php

Dockerfile

FROM php:7.0-apache
COPY ./index.php /var/www/html/

index.php

<?php
    $db_host = getenv('MYSQL_HOST', true) ?: getenv('MYSQL_HOST');
    $db_name = getenv('MYSQL_DATABASE', true) ?: getenv('MYSQL_DATABASE');
    $db_user = getenv('MYSQL_USER', true) ?: getenv('MYSQL_USER');
    $db_pwd  = getenv('MYSQL_PASSWORD', true) ?: getenv('MYSQL_PASSWORD');

    echo "db_host: {$db_host}<br>";
    echo "db_name: {$db_name}<br>";
    echo "db_user: {$db_user}<br>";
    echo "db_pwd: {$db_pwd}<br>";
?>

docker-compose.yml

version: "3.2"
services:
 www:
  build: . 
  ports:
  - "30001:80"
  - "30443:443"
  env_file:
    - .env

.env

MYSQL_ROOT_PASSWORD=RootPassword
MYSQL_USER=gnf_user
MYSQL_PASSWORD=UserPassword
MYSQL_DATABASE=gnf_noah

Compose up the container:

docker-compose up -d --build

enter image description here

Neo Anderson
  • 5,957
  • 2
  • 12
  • 29
  • I'm glad it did. Thanks for your feedback! – Neo Anderson Aug 18 '20 at 06:43
  • 1
    In this way if I type `http://localhost:30001/.env` into browser I can see the env file with passwords! – Vito Lipari Aug 18 '21 at 12:56
  • @VitoLipari, You are right: obviously, that file is served by the apache server if copied in `/www/html` and it is not needed there. I updated the answer just to make sure nobody copy-pastes that code snipped without thinking about what you said. Thanks! – Neo Anderson Aug 30 '21 at 19:50
2

To create .env file' environment variables directly into the container , we use env_file configuration option of docker

e.g.

web:
  env_file:
    - .env

It is the most subtle way to pass a list of environment variables into the container.