Загрузить переменные среды из файла env с помощью Docker и PHP
Как использовать переменные dotenv, установленные в файле Docker, переданные в приложение Php?
Недавно пытался использовать файл ".env" с набором парных значений ключей для использования в разных файлах конфигурации, но заметил, что Docker + образ Wordpress не так просто настроить. Хотя довольно тривиально настроить в узле и т. Д.
См. Файл ".env" ниже, который находится в том же каталоге, что и docker-compose.yml:
WORDPRESS_DB_NAME=wp_xxxx
WORDPRESS_DB_USER=xxxxxx
WORDPRESS_DB_PASSWORD=xxxxxx
WORDPRESS_DB_HOST=xxxxxxxx
Официальный образ Wordpress, доступный здесь ( https://hub.docker.com/_/wordpress), подтверждает, что "Следующие переменные среды также используются для настройки вашего WordPress [...] WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD и т. Д.".
По умолчанию параметры конфигурации в "wp-config.php" не заменяются переменными.env, что побудило меня расширить исходный образ Wordpress, установив композитор. Назовем файл ниже "DockerWordpress.yml":
FROM wordpress:php7.3-apache
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer && chmod +x /usr/bin/composer
RUN composer require vlucas/phpdotenv
Он используется в основном файле Docker-compose.yml, как мы видим ниже. Найдите сервис "Wordpress":
version: '3.1'
services:
web:
container_name: web
image: nginx:1.15.11-alpine
volumes:
- ./nginx/foobar.conf:/etc/nginx/conf.d/default.conf
- ../../foobar-blog-ui/public/:/var/www/html/
ports:
- 80:80
- 443:443
networks:
- foobar-wordpress-network
node:
image: node:8.16.0-slim
working_dir: /home/node/app
environment:
- NODE_ENV=development
volumes:
- ../../foobar-blog-ui/:/home/node/app
- ./node_modules:/home/node/app/node_modules
- ./npm/.npmrc:/home/node/app/.npmrc
ports:
- 8000:8000
- 9000:9000
command: bash -c "apt-get update && apt-get install -y rsync vim git libpng-dev libjpeg-dev libxi6 build-essential libgl1-mesa-glx && npm install && exit 0"
depends_on:
- wordpress
networks:
- foobar-wordpress-network
wordpress:
build:
context: .
dockerfile: ./Services/DockerWordpress.yml
container_name: wordpress
restart: on-failure
ports:
- 8888:80
environment:
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST}
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
volumes:
- ../../foobar-wordpress-cms/:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
- ./wordpress/wp-config.php:/var/www/html/wp-config.php
depends_on:
- db
networks:
- foobar-wordpress-network
wordpress-cli:
image: wordpress:cli
volumes:
- ../../foobar-wordpress-cms/:/var/www/html
- ./scripts/docker-entrypoint.sh:/var/www/html/docker-entrypoint.sh
depends_on:
- wordpress
- db
command: sh -c "sleep 30 && ./docker-entrypoint.sh"
networks:
- foobar-wordpress-network
db:
image: mariadb:latest
ports:
- 3306:3306
restart: on-failure
environment:
MYSQL_DATABASE: ${WORDPRESS_DB_NAME}
MYSQL_USER: ${WORDPRESS_DB_USER}
MYSQL_PASSWORD: ${WORDPRESS_DB_PASSWORD}
# MYSQL_ROOT_HOST: ${WORDPRESS_DB_HOST}
MYSQL_ROOT_HOST: '%'
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- ./wordpress/database:/docker-entrypoint-initdb.d
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf"
- ./mysql/data:/var/lib/mysql
networks:
- foobar-wordpress-network
healthcheck:
test: ["CMD", "mysqladmin", "-u${WORDPRESS_DB_USER}", "-p${WORDPRESS_DB_PASSWORD}", "ping"]
interval: 60s
timeout: 60s
retries: 3
volumes:
mysql_data:
node_modules:
networks:
foobar-wordpress-network:
driver: bridge
Наконец, файл "wp-config.php", который монтируется из внешнего источника в том контейнера, как вы можете видеть в предыдущем файле "docker-compose". Это делается с помощью документации, предоставленной плагином defacto, для использования переменных dotEnv ( https://github.com/vlucas/phpdotenv) в сообществе Php.
<?php
require_once(__DIR__ . './vendor/autoload.php');
(new \Dotenv\Dotenv(__DIR__ . '/../.init/Docker'))->load();
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the
* installation. You don't have to use the web site, you can
* copy this file to "wp-config.php" and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://codex.wordpress.org/Editing_wp-config.php
*
* @package WordPress
*/
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', '');
/** MySQL database username */
define( 'DB_USER', '');
/** MySQL database password */
define( 'DB_PASSWORD', '');
/** MySQL hostname */
define( 'DB_HOST', '');
/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8');
/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '');
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', 'U(p)0EQ$O;meL`Oe@1$t7nI?<$=|NJ)kb+Shya21)-M2HI#/B#e~:@gX+}h@[LNE' );
define( 'SECURE_AUTH_KEY', 'Qpe;9 Ye^zuSozw@}2*f9mK~]7/V1,gf[^v4=}@ N!$<(q2qI<3U]kNK^P4b)n;7' );
define( 'LOGGED_IN_KEY', 'R=yN?s&Ek8ncd;xuvIHU];2fo#piE[MbF6 63@aP:p1TyZmz#94(>XErht{}6<V,' );
define( 'NONCE_KEY', 'Xr~QqP8%cjPA$] ?m*-CrcjgdfA6Vao>8C/AI6-pi_Y<rI]y=6fKSOS6i/%4F~Xl' );
define( 'AUTH_SALT', '<<7vysQ=uPfNxyl? z=97AyIfm~QNn5%JI7^)bFW&;A`V.5`W2xj+KXJY`_hV66T' );
define( 'SECURE_AUTH_SALT', 'dT-4]:wh_.++<M&L6>&Eywn})wSzy+.`v6eBhl694uF(fc:yp9:?oV! PDbU(ST(' );
define( 'LOGGED_IN_SALT', '3rPPnmKp|dUR=KX{W-TVYH7a:60P7z}$h3jgggKJgn~9XX`)6XuCtzMLjypztu!m' );
define( 'NONCE_SALT', 'X4aAby}iQOenS$2g7~R@,9+/-mc_lfzq!*RMP+cKOgv0K[{xS73~|k0u:zq>G.My' );
/**#@-*/
/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the Codex.
*
* @link https://codex.wordpress.org/Debugging_in_WordPress
*/
// define( 'WP_DEBUG', true );
// define( 'WP_DEBUG_LOG', true );
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}
/** Sets up WordPress vars and included files. */
require_once( ABSPATH . 'wp-settings.php' );
Поскольку я использую композитор и плагин phpdotnet, я также пробовал:
define( 'DB_NAME', getenv('WORDPRESS_DB_NAME'));
...
В журнале ошибок я могу прочитать:
wordpress exited with code 4
Ошибка выше code 4
вызывается предоставлением "переменных среды", что заставляет сценарий точки входа пытаться изменить за нас wp-config.php.
Поскольку code 4
вызывается переменными среды, с или без проверки изображения докера возвращает следующее (не имеет переменных env):
[
{
"Id": "sha256:0d91452f5f88a168d9e85e2c4992460e2ef50d66d60c581c3ffc60b78824a416",
"RepoTags": [
"docker_wordpress:latest"
],
"RepoDigests": [],
"Parent": "sha256:73c390be73f955ac64e67751faba8095ed0d31a98a3eb841ea38be6a81d9bd02",
"Comment": "",
"Created": "2019-09-09T22:54:10.8766881Z",
"Container": "20a95e0640aa65d9c1c244cdacf0dae09165c4da3ff19460190dce4cf4a80d8b",
"ContainerConfig": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PHPIZE_DEPS=autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c",
"PHP_INI_DIR=/usr/local/etc/php",
"APACHE_CONFDIR=/etc/apache2",
"APACHE_ENVVARS=/etc/apache2/envvars",
"PHP_EXTRA_BUILD_DEPS=apache2-dev",
"PHP_EXTRA_CONFIGURE_ARGS=--with-apxs2 --disable-cgi",
"PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2",
"PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2",
"PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie",
"GPG_KEYS=CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D",
"PHP_VERSION=7.3.9",
"PHP_URL=https://www.php.net/get/php-7.3.9.tar.xz/from/this/mirror",
"PHP_ASC_URL=https://www.php.net/get/php-7.3.9.tar.xz.asc/from/this/mirror",
"PHP_SHA256=4007f24a39822bef2805b75c625551d30be9eeed329d52eb0838fa5c1b91c1fd",
"PHP_MD5=",
"WORDPRESS_VERSION=5.2.3",
"WORDPRESS_SHA1=5efd37148788f3b14b295b2a9bf48a1a467aa303"
],
"Cmd": [
"/bin/sh",
"-c",
"composer require vlucas/phpdotenv"
],
"Image": "sha256:73c390be73f955ac64e67751faba8095ed0d31a98a3eb841ea38be6a81d9bd02",
"Volumes": {
"/var/www/html": {}
},
"WorkingDir": "/var/www/html",
"Entrypoint": null,
"OnBuild": null,
"Labels": null,
"StopSignal": "WINCH"
},
"DockerVersion": "19.03.2",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PHPIZE_DEPS=autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c",
"PHP_INI_DIR=/usr/local/etc/php",
"APACHE_CONFDIR=/etc/apache2",
"APACHE_ENVVARS=/etc/apache2/envvars",
"PHP_EXTRA_BUILD_DEPS=apache2-dev",
"PHP_EXTRA_CONFIGURE_ARGS=--with-apxs2 --disable-cgi",
"PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2",
"PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2",
"PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie",
"GPG_KEYS=CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D",
"PHP_VERSION=7.3.9",
"PHP_URL=https://www.php.net/get/php-7.3.9.tar.xz/from/this/mirror",
"PHP_ASC_URL=https://www.php.net/get/php-7.3.9.tar.xz.asc/from/this/mirror",
"PHP_SHA256=4007f24a39822bef2805b75c625551d30be9eeed329d52eb0838fa5c1b91c1fd",
"PHP_MD5=",
"WORDPRESS_VERSION=5.2.3",
"WORDPRESS_SHA1=5efd37148788f3b14b295b2a9bf48a1a467aa303"
],
"Cmd": [
"apache2-foreground"
],
"ArgsEscaped": true,
"Image": "sha256:73c390be73f955ac64e67751faba8095ed0d31a98a3eb841ea38be6a81d9bd02",
"Volumes": {
"/var/www/html": {}
},
"WorkingDir": "/var/www/html",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": null,
"StopSignal": "WINCH"
},
"Architecture": "amd64",
"Os": "linux",
"Size": 530754564,
"VirtualSize": 530754564,
"GraphDriver": {
"Data": {
...
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
...
]
},
"Metadata": {
"LastTagTime": "2019-09-09T22:54:10.9465719Z"
}
}
]
Имейте в виду, что я ожидаю, что документация верна и что настройки выше должны быть соблюдены.
3 ответа
Вот несколько заметок, которые помогли мне найти решение, и надеюсь, что оно поможет кому-то еще в будущем.
Сначала проблемы, которые я обнаружил, пытаясь и наблюдая:
первый, который вызвал ошибку, представленную выше как
wordpress exited with code 4
заключается в том, что wp-content.php не работает при монтировании в контейнер, поэтому либо намерение состоит в том, чтобы позволить сценарию sh точки входа "wordpress" изменить файл за нас, либо accept будет делать что-то еще, как описано выше, плагин phpdotenv и $_ENV или getenv fn (https://www.php.net/manual/en/function.getenv.php)том монтируется в файл Docker-compose.yml и перезаписывает файлы, такие как те, которые мы пытаемся скопировать в контейнер WORKDIR и т. д.
Контекст Docker-compose не позволяет копировать файлы за пределами его области действия "Путь должен находиться внутри контекста сборки"
Ниже вы найдете рабочую версию (WIP), которая сработала для меня в качестве альтернативы поведению по умолчанию, которое, как указано, должно соблюдаться (я считаю, что рефакторинг, учитывая упомянутые выше моменты, принимая во внимание все, это может можно улучшить, но давайте оставим это связанным с передачей dotenv в PHP, это должно быть полезно для кого-то еще в будущем).
++++++++++++ docker-compose.yml ++++++++++++++++
version: '3.1'
services:
web:
container_name: web
image: nginx:1.15.11-alpine
volumes:
- ./nginx/foobar.conf:/etc/nginx/conf.d/default.conf
- ../../foobar-blog-ui/public/:/var/www/html/
ports:
- 80:80
- 443:443
networks:
- foobar-wordpress-network
node:
image: node:8.16.0-slim
working_dir: /home/node/app
environment:
- NODE_ENV=development
volumes:
- ../../foobar-blog-ui/:/home/node/app
- ./node_modules:/home/node/app/node_modules
- ./npm/.npmrc:/home/node/app/.npmrc
ports:
- 8000:8000
- 9000:9000
command: bash -c "apt-get update && apt-get install -y rsync vim git libpng-dev libjpeg-dev libxi6 build-essential libgl1-mesa-glx && npm install && exit 0"
depends_on:
- wordpress
networks:
- foobar-wordpress-network
wordpress:
build:
context: ../../
dockerfile: ./.init/Docker/Services/DockerWordpress.yml
container_name: wordpress
restart: on-failure
ports:
- 8888:80
depends_on:
- db
networks:
- foobar-wordpress-network
wordpress-cli:
image: wordpress:cli
volumes:
- ../../foobar-wordpress-cms/:/var/www/html
- ./scripts/docker-entrypoint.sh:/var/www/html/docker-entrypoint.sh
depends_on:
- wordpress
- db
command: sh -c "sleep 30 && ./docker-entrypoint.sh"
networks:
- foobar-wordpress-network
volumes:
node_modules:
networks:
foobar-wordpress-network:
driver: bridge
++++++++++++ dockerfile ++++++++++++++++
FROM wordpress:php7.3-apache
WORKDIR /var/www/html/
COPY ./.init/Docker/.env .
COPY ./foobar-wordpress-cms .
COPY ./.init/Docker/php/uploads.ini /usr/local/etc/php/conf.d/uploads.ini
COPY ./.init/Docker/wordpress/wp-config.php ./wp-config.php
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer && chmod +x /usr/bin/composer
RUN composer require vlucas/phpdotenv
RUN ls -la
Следующая статья также помогла ( https://vsupalov.com/docker-arg-env-variable-guide/).
Переменные среды в Docker
Настроить .env
в docker-compose.yml
Файл Environmnet.env
WORDPRESS_DB_NAME=platform-ops-db
docker-compose.yml
version: '2'
services:
web:
image: nginx:1.15.11-alpine
container_name: web
env_file:
- ./.env
environment:
MYSQL_DATABASE: ${WORDPRESS_DB_NAME}
Мы можем использовать WORDPRESS_DB_NAME
во всем приложении, работающем внутри контейнера web
.
Чтобы запустить Wordpress в контейнере за прокси, проверьте файл конфигурации репозитория Wordpress в качестве контейнера за прокси в репо Репо
Поскольку код 4 вызван переменными среды, с или без изображения докера inspect возвращает следующее (не имеет переменных env):
Вы смешиваете две вещи dotenv
против system environment variable
. Вdotenv
приоритет всегда ниже, чем у системной переменной среды, и вы не можете видеть dotenv
переменная в docker inspect
.
Чтобы установить env в Docker, он должен быть в Dockerfile ( docker inspect will work)
или должен быть передан для запуска команды во время создания.
docker exec you_container_name bash -c "printenv"
это напечатает системную переменную среды, а не dotenv
.
Неизменность
По умолчанию Dotenv НЕ перезаписывает существующие переменные среды, которые уже установлены в среде.
Если вы хотите, чтобы Dotenv перезаписывал существующие переменные среды, используйте overload вместо load:
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->overload();
Поэтому я предлагаю установить в системной среде WordPress, если он не выбирает из dotenv
или должен выбирать из system
переменная окружения.