简体   繁体   English

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

[英]Load environment variables from env file with Docker and PHP

How to use dotenv variables set in the Docker file, passed to a Php application? 如何使用传递给Php应用程序的Docker文件中设置的dotenv变量?

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. 最近尝试使用带有一组密钥对值的“ .env”文件在不同的配置文件中使用,但是注意到Docker + Wordpress映像不容易设置。 While quite trivial to set up in node, etc. 虽然在节点等中设置非常简单。

See the ".env" file below that sits same dir as the docker-compose.yml: 请参阅下面的“ .env”文件,该文件与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". 可在此处( https://hub.docker.com/_/wordpress )获得的官方Wordpress图像文档“以下环境变量也因配置WordPress WORDPRESS_DB_USER,WORDPRESS_DB_PASSWORD等而受到欢迎”。

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. 默认情况下,“ wp-config.php”中的配置参数不会替换为.env变量,这使我可以通过安装composer扩展原始Wordpress图像。 Let's call the file bellow "DockerWordpress.yml": 我们将以下文件称为“ 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. 正如在下面看到的那样,它在主要的Docker-compose.yml文件中使用。 Find the service "Wordpress": 查找服务“ 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. 最后,从外部源安装到容器卷中的“ wp-config.php”文件,如您在前面的“ docker-compose”文件中所见。 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. 这是通过遵循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' );

Since I'm using composer and the phpdotnet plugin, I've also tried: 由于我使用的是作曲家和phpdotnet插件,因此我也尝试过:

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. 上面code 4的错误是由提供“环境变量”引起的,该环境变量导致入口点脚本尝试为我们修改wp-config.php。

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): 由于code 4是由环境变量引起的,因此无论是否带有inspect 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"
        }
    }
]

Have in mind that I expect that the documentation is correct and that the setup above, that the environment variables should be honoured. 请记住,我希望文档是正确的,并且应该遵循上面的设置,并尊重环境变量。

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 ) 第一个导致上述因wordpress exited with code 4而导致的错误的原因是wp-content.php在装入容器时失败,因此,其目的是允许“ wordpress”入口点sh脚本为我们修改文件,或者如上文所述,accept还会做其他事情,如插件phpdotenv和$ _ENV或getenv fn( https://www.php.net/manual/zh/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 该卷安装在Docker-compose.yml文件中并覆盖文件,例如我们尝试将其复制到容器WORKDIR中的文件等

  • The Docker-compose context doesn't allow copying files outside its scope "The path must be inside the context of the build" Docker-compose上下文不允许在其范围外复制文件“路径必须在构建上下文内”

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). 在下面,您会找到一个对我有用的工作版本(WIP),它是默认行为的替代方式,应该遵循上述默认行为(我相信,鉴于上述要点,考虑到所有因素,重构可以做到这一点。有待改进,但让我们将此与将dotenv传递给PHP保持联系,将来对其他人会很有用)。

++++++++++++ docker-compose.yml ++++++++++++++++ ++++++++++++ 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 ). 以下文章也有所帮助( https://vsupalov.com/docker-arg-env-variable-guide/#the-dot-env-file-env )。

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): 由于代码4是由环境变量引起的,因此无论是否带有inspect docker镜像,都将返回以下内容(不包含env变量):

You are mixing two things dotenv vs system environment variable . 您将dotenvsystem environment variable dotenv The dotenv priority is always lowered than the system environment variable and you can not see dotenv variable in docker inspect . dotenv优先级始终低于系统环境变量,并且您无法在dotenv docker inspect看到dotenv变量。

To set env in Docker it should be in Dockerfile ( docker inspect will work) or should be pass to run the command at creation time. 要在Docker中设置env,它应该在Dockerfile中( docker inspect will work) docker ( docker inspect will work)或者应该在创建时传递以运行命令。

在此处输入图片说明

docker exec you_container_name bash -c "printenv" this will print the system environment variable, not dotenv . docker exec you_container_name bash -c "printenv"这将打印系统环境变量,而不是dotenv

在此处输入图片说明

Immutability 不变性

By default, Dotenv will NOT overwrite existing environment variables that are already set in the environment. 默认情况下,Dotenv不会覆盖环境中已经设置的现有环境变量。

If you want Dotenv to overwrite existing environment variables, use overload instead of load: 如果要让Dotenv覆盖现有的环境变量,请使用重载而不是负载:

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

So I will suggest setting in system environment for WordPress if it not picking from dotenv or supposed to pick from system environment variable. 因此,如果不从dotenv或应该从system环境变量中选取,我建议在WordPress中在系统环境中进行设置。

phpdotenv phpdotenv

secure-your-wordpress-config-with-dotenv 使用dotenv保护您的wordpress配置

Environment Variables in Docker Docker中的环境变量

Setup .env in docker-compose.yml 设置.envdocker-compose.yml

Environmnet File .env 环境文件.env

WORDPRESS_DB_NAME=platform-ops-db

docker-compose.yml 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 . 我们可以在整个与容器web运行的应用程序中使用WORDPRESS_DB_NAME

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 要在代理后面的容器中运行Wordpress,请检查repo conf文件Wordpress作为 仓库中 在代理后面的容器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM