使用Docker和PHP从env文件加载环境变量

时间:2019-09-09 22:29:51

标签: php wordpress docker docker-compose phpdotenv

如何使用传递给Php应用程序的Docker文件中设置的dotenv变量?

最近尝试使用带有一组密钥对值的“ .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变量,这导致我通过安装composer扩展了原始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插件提供的文档以在Php社区中使用dotEnv变量(https://github.com/vlucas/phpdotenv)来完成的。

<?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是由环境变量引起的,因此无论是否带有检查docker映像,都将返回以下内容(没有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 个答案:

答案 0 :(得分:0)

这里有一些说明可以帮助我找到解决方案,并希望将来对其他人有所帮助。

首先,我尝试查看时发现的问题:

  • 第一个导致上述错误为wordpress exited with code 4的错误是wp-content.php在装入容器时失败,因此,其目的是允许“ wordpress”入口点sh脚本执行以下操作:为我们修改文件或接受该文件会做其他事情,如上所述,插件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/#the-dot-env-file-env)。

答案 1 :(得分:0)

  

由于代码4是由环境变量引起的,请使用或   没有检查docker映像返回以下内容(没有   env变量):

您正在将dotenvsystem environment variable混为一谈。 dotenv优先级始终低于系统环境变量,并且在dotenv中看不到docker inspect变量。

要在Docker中设置环境,它应位于Dockerfile ( docker inspect will work)中,或者应在创建时传递以运行命令。

enter image description here

docker exec you_container_name bash -c "printenv"将打印系统环境变量,而不是dotenv

enter image description here

不可移植性

  

默认情况下,Dotenv不会覆盖现有的环境变量   已经在环境中设置的

     

如果要让Dotenv覆盖现有环境变量,请使用   重载而不是负载:

$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->overload();

因此,我建议您在WordPress的系统环境中进行设置,如果它不是从dotenv中选取或应该从system环境变量中选取。

phpdotenv

secure-your-wordpress-config-with-dotenv

答案 2 :(得分:0)

Docker中的环境变量

.env中设置docker-compose.yml

环境文件.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 as a container behind the proxy中的仓库conf文件Repo