首页 > 解决方案 > 使用环境变量从 docker 容器上运行的 php YII 应用程序连接到 RDS mysql 数据库

问题描述

我在 aws ecs 上运行了几个 docker 容器,全部在 php Yii 应用程序上运行。

应用程序需要连接到 AWS RDS 数据库。目前数据库名称、主机、用户名和密码被硬编码在文件“main-local.php”中

  'components' => [
    'db' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'mysql:host=dbinstancename.xxxxx.region.rds.amazonaws.com;dbname=xxxxxxx',
        'username' => 'xxxxxxxx',
        'password' => 'xxxxxxxx',
        'charset' => 'utf8',
    ],

我知道在 docker 容器中对数据库详细信息进行硬编码并不是最佳实践。我可以在运行时将环境变量传递给 docker,例如“DB_HOST”、“DB_NAME”、“DB_USER”、“DB_PASSWORD”以及相应的值。我可以在 docker 容器中看到相同的细节,输入命令“env”

如何在 main-local.php 中使用它?我们可以直接用环境变量替换代码中的数据库细节吗?这是要从开发人员端做的事情吗?

标签: dockeryiienvironment-variablesamazon-ecs

解决方案


要添加 env 支持,您可以使用此扩展程序https://github.com/vlucas/phpdotenv

只需安装它

composer.phar require vlucas/phpdotenv

创建.env文件。它应该在.gitignore并且不能从网络访问。如果您使用的是基本或高级模板,请将其yii.bat放入项目根目录中。您也可以.env.example使用空变量创建。

YII_DEBUG=1
YII_TRACE_LEVEL=3
YII_ENV=dev

然后像这样将它添加到你的 index.php

require_once __DIR__ . '/protected/vendor/autoload.php';

$factory = new Dotenv\Environment\DotenvFactory([
    new Dotenv\Environment\Adapter\EnvConstAdapter(),
]);
// Specify path to directory with .env file here (for advanced you should up twice)
\Dotenv\Dotenv::create(__DIR__ . DIRECTORY_SEPARATOR . '/../', null, $factory)->load();

defined('YII_DEBUG') or define('YII_DEBUG', (bool) $_ENV['YII_DEBUG']);
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', $_ENV['YII_TRACE_LEVEL']);
defined('YII_ENV') or define('YII_ENV', $_ENV['YII_ENV']);

我建议只使用 EnvConstAdapter。导致$_SERVER变量被记录,并且getenv()有时在并发请求上有空值。

和空字符串bool的小改进。在实例化null之前添加它并改用.$factoryenv()$_ENV

if (!function_exists('env')) {
    /**
     * Gets the value of an environment variable.
     * @param string $key
     * @param mixed $default
     * @return mixed
     */
    function env($key, $default = null)
    {
        if (!isset($_ENV[$key])) {
            return $default;
        }

        $value = $_ENV[$key];

        switch ($value) {
            case 'true':
            case '(true)':
                return true;
            case 'false':
            case '(false)':
                return false;
            case 'empty':
            case '(empty)':
                return '';
            case 'null':
            case '(null)':
                return null;
            default:
                return $value;
        }
    }
}

推荐阅读