【问题标题】:How to load multiple .env files or load .env from parent directory in Laravel 6如何在 Laravel 6 中加载多个 .env 文件或从父目录加载 .env
【发布时间】:2020-06-19 08:34:19
【问题描述】:

对于使用 docker-compose 的 Laravel 应用程序,我有以下(简化的)文件夹结构:

Project
|
|-- data
    |-- ...
|-- docker
    |-- ...
|-- laravel
    |-- app
    |-- ...
    |-- .env
|-- docker-compose.yml
|-- .env

Docker-compose 设置为在构建容器时从项目根文件夹中的.env 文件加载数据库连接详细信息。 Laravel 也需要这些,我必须将它们复制到 laravel 文件夹内的 .env 文件中。

我想避免这种重复。理想情况下,我会在 Laravel 中加载两个 .env 文件,以避免将 docker-compose .env 与仅与 Laravel 相关的东西弄得一团糟。但是如果有一种干净的方法可以做到这一点,我几乎会很高兴在项目根目录中拥有一个 .env 文件。

我在Illuminate\Foundation\Application 中没有找到配置设置,但没有找到相关方法loadEnvironmentFrom()useEnvironmentPath(),但我不知道从哪里调用它们。我会扩展应用程序,但似乎 Dotenv 在 /boostrap/app.php 中实例化时已经加载了

希望在供应商 dolder 之外的某个地方,我可以及时更改路径或加载不同的 .env 文件,以便配置文件使用它。非常感谢您的帮助

【问题讨论】:

    标签: php docker configuration laravel-6 dotenv


    【解决方案1】:

    bootstrap/app.php 中使用useEnvironmentPath()

    $app->useEnvironmentPath($env_path);
    

    或者作为解决方案:

    $app->useEnvironmentPath(
      dirname(__DIR__, 2)
    );
    

    __DIR__ 返回当前文件的完整路径(因为您在 bootstrap/app.php
    dirname(__DIR__, 2),从您的文件位置返回 2 个步骤(在您的情况下,它返回您的 Project 目录路径)

    现在 Laravel 应该读取你的新 .env 文件。

    -- 更新--

    对于 HTTP 应用程序,更新 app/Http/Kernel.php

    use Illuminate\Routing\Router;
    use Illuminate\Contracts\Foundation\Application;
    //////
        /**
         * Create a new HTTP kernel instance.
         *
         * @param  \Illuminate\Contracts\Foundation\Application  $app
         * @param  \Illuminate\Routing\Router  $router
         * @return void
         */
        public function __construct(Application $app, Router $router)
        {
            $app->useEnvironmentPath(dirname(__DIR__, 3));
            parent::__construct($app, $router);
        }
    

    对于控制台应用程序,编辑app/Console/Kernel.php

    use Illuminate\Contracts\Events\Dispatcher;
    use Illuminate\Contracts\Foundation\Application;
    
    /////
        /**
         * Create a new console kernel instance.
         *
         * @param  \Illuminate\Contracts\Foundation\Application  $app
         * @param  \Illuminate\Contracts\Events\Dispatcher  $events
         * @return void
         */
        public function __construct(Application $app, Dispatcher $events)
        {
            $app->useEnvironmentPath(dirname(__DIR__, 3));
            parent::__construct($app, $events);
        }
    

    还有app/Providers/AppServiceProvider.php:

    public function boot() {
        app()->useEnvironmentPath(dirname(__DIR__, 3));
    }
    

    【讨论】:

    • 不幸的是,这只有一半有效。也就是说,artisan 加载了正确的 .env 文件,我可以通过 tinker 运行迁移、种子和查询;但是当我通过 HTTP 请求路由时,任何路由都会出现 db connect 错误,或者如果路由不涉及 db 查询,则会出现无法解决的缺少应用程序键错误,这表明 .env 没有被加载。
    • 经过进一步测试,我意识到您的原始解决方案使用 artisan 而不是通过 HTTP 的原因是 apache 容器将 laravel 目录映射到 /var/www/html 并且无法访问父目录?‍♂️。当我尝试在本地运行您的解决方案运行良好的项目时,我意识到了这一点。所以我选择你的答案是正确的,因为它确实符合我的要求,但看起来我最终可能会将 docker 配置为从 laravel 目录读取 env 文件,而不是使用你的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2020-03-26
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多