I created my own dockerfile (ubuntu:xenial) using environment variables. This dockerfile uses php7.0-fpm php7.0-xml php7.0-mbstring php-mysql
The dockerfiles contains:
ENV MYSQL_HOST=192.168.0.2
ENV MYSQL_DBNAME=dbname_xyz
ENV MYSQL_USERNAME=username_xyz
ENV MYSQL_PASSWORD=password_xyz
...
RUN echo "clear_env = no" >> /etc/php/7.0/fpm/pool.d/www.conf
in the server.php I'm trying to use those variables, but they aren't known obviously
$host = $_SERVER["MYSQL_HOST"];
$dbname = $_SERVER["MYSQL_DBNAME"];
$username = $_SERVER["MYSQL_USERNAME"];
$password = $_SERVER["MYSQL_PASSWORD"];
$pdo = new \PDO("mysql:host=$host;dbname=$dbname", $username, $password);
Running that shows error:
FastCGI sent in stderr: "PHP message: PHP Notice: Undefined index: MYSQL_HOST in /var/webdav/server.php on line 4
Executing on: container-shell shows correct value
php -r "echo getenv('MYSQL_HOST');"
env | grep MYSQL
Any suggestions what I've to change?
UPDATE 20211215 after AymDEV's feedback
UPDATE 20211215 after piotrekkr's feedback
Full dockerfile:
FROM ubuntu:xenial
MAINTAINER [email protected]
# Changing WEBDAV_PASSWORD doesn't work
# MYSQL_x aren't known to server.php
ENV WEBDAV_USERNAME=admin
ENV WEBDAV_PASSWORD=admin
ENV MYSQL_HOST=192.168.0.2
ENV MYSQL_DBNAME=dbname_xyz
ENV MYSQL_USERNAME=username_xyz
ENV MYSQL_PASSWORD=password_xyz
# Defaults
WORKDIR /var/webdav
VOLUME /var/webdav/public
VOLUME /var/webdav/data
# Install zip
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y zip unzip php-zip
# Install nginx with php7 support
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y nginx php7.0-fpm php7.0-xml php7.0-mbstring php-mysql && \
rm -rf /var/lib/apt/lists/*
# Install SabreDAV
RUN php -r "readfile('http://getcomposer.org/installer');" > composer-setup.php && \
php composer-setup.php --install-dir=/usr/bin --filename=composer && \
php -r "unlink('composer-setup.php');" && \
composer require sabre/dav ~3.2.2 && \
rm /usr/bin/composer
# Set up entrypoint
COPY /scripts/install.sh /install.sh
# Configure nginx
COPY /config/nginx/default /etc/nginx/sites-enabled/default
COPY /config/nginx/fastcgi_params /etc/nginx/fastcgi_params
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log
# copy server.php for client -- sabredav communication
COPY /web/server.php /var/webdav/server.php
#make environment variables available to php
RUN echo "clear_env = no" >> /etc/php/7.0/fpm/pool.d/www.conf
#nginx will be process with PID=1
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
CMD /install.sh && service php7.0-fpm start && nginx
full server.php
<?php
date_default_timezone_set('Europe/Berlin');
$baseUri = '/';
$host = $_ENV["MYSQL_HOST"];
$dbname = $_ENV["MYSQL_DBNAME"];
$username = $_ENV["MYSQL_USERNAME"];
$password = $_ENV["MYSQL_PASSWORD"];
$pdo = new \PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
require_once 'vendor/autoload.php';
$authBackend = new \Sabre\DAV\Auth\Backend\PDO($pdo);
$principalBackend = new \Sabre\DAVACL\PrincipalBackend\PDO($pdo);
$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);
$caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo);
$nodes = [
new \Sabre\CalDAV\Principal\Collection($principalBackend),
new \Sabre\CalDAV\CalendarRoot($principalBackend, $caldavBackend),
new \Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend),
];
$server = new \Sabre\DAV\Server($nodes);
if (isset($baseUri)) $server->setBaseUri($baseUri);
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
$server->addPlugin(new \Sabre\DAV\Browser\Plugin());
$server->addPlugin(new \Sabre\CalDAV\Plugin());
$server->addPlugin(new \Sabre\CardDAV\Plugin());
$server->addPlugin(new \Sabre\DAV\Sync\Plugin());
$server->exec();
Actually - everything is working as designed. There are several reasons why you are not seeing the ENV variables and the approach you are using is a bit flawed.
TLDR: use docker-compose and split the FPM process into a separate container, with fpm as the entrypoint.
Why it doesn't work
Since this case is a bit complex - I will try to go step by step by the reasons why it's not working for you. Hopefully this will help.
Your PHP scripts are executed within the FPM workers. Each of these workers passes specific data (context) into PHP. That context you can see, for example, inside the $_SERVER variable:
If you print out the same variable from the CLI - the result will be quite different (I guess you already observed that):
The ENV is properly passed into the container and if you execute processes in the container - the ENV is available to them. This is seen in the second example above. But, if you look at the processes running in your container:
you can examine the environment of each one of them, see process with PID=1 (the entrypoint of the container):
the environment has the ENVs that you created. All good here. But if you look at the FPM process:
it's empty!
This is because you are running the FPM as a service (as in a systemd service), which means that you would have to define these environment variables within the service's configuration file, in this case
/lib/systemd/system/php7.0-fpm.service.It can be done, however - it wouldn't be very clean to do so.
What you can do to fix it
You can work around the problems above by simply using php-fpm as the entrypoint to your container. That way - it will have access to the ENV. This is already being done by the official
php-fpmimages and we can try to use them. Here's a minimal workable example, using docker-compose:docker-compose.yml:
Now, in the same folder create html/print.php:
and conf/default.conf:
with this - simply run
docker-compose up -dand thencurl localhost:8080/print.php.This should give you the expected env variable
MYSQL_PASSinside your$_SERVERarray: