mysql — доступ к переменным среды в контейнерах Docker, связанных с —link

Я настраиваю среду разработки для своего приложения в контейнерах Docker, на данный момент у меня есть эти контейнеры:

myapp-data       - Holds application source code and log files
myapp-phpfpm     - Runs the php5-fpm process for Nginx
myapp-nginx      - Runs the Nginx web server that serves the application

Эта установка работает прекрасно, я действительно доволен этим. Но моему приложению нужна база данных MySQL для подключения, поэтому я использую официальный образ MySQL, и работает так:

sudo docker run --name myapp-mysql -e "MYSQL_ROOT_PASSWORD=iamroot" -e "MYSQL_USER=redacted" -e "MYSQL_PASSWORD=redacted" -e "MYSQL_DATABASE=redacted" -d mysql

Это также прекрасно работает. Но мой myapp-phpfpm Контейнер должен быть связан с myapp-mysql Контейнер, чтобы выставить детали подключения MySQL к моему приложению. Поэтому я перезагружаю myapp-phpfpm контейнер:

sudo docker run --privileged=true --name myapp-phpfpm --volumes-from myapp-data --link myapp-mysql:mysql -d readr/phpfpm

Так что теперь мой myapp-phpfpm Контейнер связан с моим myapp-mysql контейнер, поэтому я должен иметь доступ к базе данных в моем приложении PHP.

Проблема в том, что я не могу. Переменные среды не существуют внутри приложения PHP. Если я сделаю:

die(var_dump(`printenv`));

Я не получаю переменные среды MySQL. Чтобы попытаться отладить, я сделал whoami чтобы узнать, как работает пользователь PHP, www-data, Затем я создал процесс Bash внутри контейнера, использовал su www-data стать www-data пользователь и сделал printenv там. Конечно же, переменные среды MySQL там существуют:

MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_PORT_3306_TCP=tcp://172.17.1.118:3306
MYSQL_ENV_MYSQL_ROOT_PASSWORD=iamroot
... etc ...

Итак, как я могу получить доступ к переменным окружения, которые Docker раскрывает о моем myapp-mysql контейнер внутри PHP?

1

Решение

Я решил это путем создания кастома start.sh сценарий, который затем вызывается из моего Dockerfile:

#!/bin/sh

# Function to update the fpm configuration to make the service environment variables available
function setEnvironmentVariable() {
if [ -z "$2" ]; then
echo "Environment variable '$1' not set."return
fi

# Check whether variable already exists
if grep -q $1 /etc/php5/fpm/pool.d/www.conf; then
# Reset variable
sed -i "s/^env\[$1.*/env[$1] = $2/g" /etc/php5/fpm/pool.d/www.conf
else
# Add variable
echo "env[$1] = $2" >> /etc/php5/fpm/pool.d/www.conf
fi
}

# Grep for variables that look like MySQL (MYSQL)
for _curVar in `env | grep MYSQL | awk -F = '{print $1}'`;do
# awk has split them by the equals sign
# Pass the name and value to our function
setEnvironmentVariable ${_curVar} ${!_curVar}
done

# start php-fpm
exec /usr/sbin/php5-fpm

Затем это добавляет переменные окружения в конфигурацию PHP5-FPM, чтобы они могли быть доступны из скриптов PHP.

1

Другие решения

php-fpm по умолчанию очищает все переменные окружения, /etc/php5/fpm/pool.d/www.conf:

; Setting to "no" will make all environment variables available to PHP code
; via getenv(), $_ENV and $_SERVER.
; Default Value: yes
;clear_env = no

Вы можете исправить это, раскомментировав в своем Dockerfile:

RUN sed -i -e "s/;clear_env\s*=\s*no/clear_env = no/g" /etc/php5/fpm/pool.d/www.conf
1

Я бы порекомендовал использовать что-то вроде fig и просто передать env vars в оба контейнера при запуске. Если вы действительно хотите, чтобы вы могли docker inspect любой контейнер из любого другого контейнера, если вы подключите и подключите докер-сокет, то сделайте что-то вроде этого:

docker inspect -f {{.Config.Env}} myapp-mysql
0

Проблема может быть не в переменных среды — это может быть ваша установка PHP.

TL; DR Переменные среды, доступные при запуске приложения под Apache & PHP может быть недоступен, если вы используете nginx или lighttpd и fastcgi.

Длинная версия

Вот то, как я это понимаю (и это, вероятно, неправильно или неполно, потому что мой опыт с этим весьма ограничен). Поскольку PHP не работает как часть браузера в nginx с fastCGI, он не имеет доступа к оболочке, в которой был запущен браузер, и поэтому не имеет доступа к переменным среды в этой оболочке.

Решение состоит в том, чтобы объявить интересующие вас переменные как часть конфигурации. Этот ответ довольно кратко, но в нем содержится основной ответ на эту проблему.

0
По вопросам рекламы [email protected]