Load environment variables from env file with Docker and PHP
Solution 1
Here're a few notes that helped me found the solution, and hope it helps someone else in the future.
First the issues I found while trying and seeing:
the first one that caused the error exposed above as
wordpress exited with code 4
is that wp-content.php fails when mounted into the container, so either the intention is to allow the "wordpress" entrypoint sh script to modify the file for us or accept will do something else, as tried above, the plugin phpdotenv and $_ENV or getenv fn (https://www.php.net/manual/en/function.getenv.php)the volume is mounted in the Docker-compose.yml file and overwrites files such as the ones we try to COPY into the container WORKDIR, etc
The Docker-compose context doesn't allow copying files outside its scope "The path must be inside the context of the build"
Below you'll find a working version (WIP), that worked for me, as an alternative to the default behaviour that, as stated should be honoured (I believe that refactoring, given the points mentioned above, taking into consideration all, this can be improved, but let's keep this related with passing dotenv to PHP, should be useful for someone else in the future).
++++++++++++ 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
The following article also helped ( https://vsupalov.com/docker-arg-env-variable-guide/#the-dot-env-file-env ).
Solution 2
Environment Variables in Docker
Setup .env
in docker-compose.yml
Environmnet File .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}
We can use the WORDPRESS_DB_NAME
throughout the application running withing the container web
.
To run the Wordpress in a container behind the proxy please check with the repo conf file Wordpress as a container behind the proxy in the repo Repo
Comments
-
punkbit almost 2 years
How to use dotenv variables set in the Docker file, passed to a Php application?
Recently tried to use a ".env" file with a set of key paired values to use across different configuration files, but noticed that Docker + the Wordpress image is not easy to setup. While quite trivial to set up in node, etc.
See the ".env" file below that sits same dir as the docker-compose.yml:
WORDPRESS_DB_NAME=wp_xxxx WORDPRESS_DB_USER=xxxxxx WORDPRESS_DB_PASSWORD=xxxxxx WORDPRESS_DB_HOST=xxxxxxxx
The official Wordpress image available here ( https://hub.docker.com/_/wordpress ) documents that "The following environment variables are also honoured for configuring your WordPress [...] WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD, etc".
By default the Configuration parameters in the "wp-config.php" are not replaced by the .env variables, which lead me to extend the original Wordpress image by installing composer. Let's call the file bellow "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
That is used in the main Docker-compose.yml file, as we can see below. Find the service "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
Finally, the "wp-config.php" file that is mounted from an external source into the container volume, as you can see in the previous "docker-compose" file. This is done by following the documentation provided by the defacto plugin to use dotEnv variables ( https://github.com/vlucas/phpdotenv ) in the Php community.
<?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' );
Since I'm using composer and the phpdotnet plugin, I've also tried:
define( 'DB_NAME', getenv('WORDPRESS_DB_NAME')); ...
In the error log, I can read:
wordpress exited with code 4
The error above
code 4
is caused by providing "environment variables", that causes the entrypoint script to try to modify the wp-config.php for us.Since the
code 4
is caused by the environment variables, with or without the inspect docker image returns the following (does not have env variables):[ { "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" } } ]
Have in mind that I expect that the documentation is correct and that the setup above, that the environment variables should be honoured.
-
thicolares about 3 yearsImportant: so far, it only works if both .env and docker-compose.yml are in the same folder.