kaan_atakan
kaan_atakan

Reputation: 4047

How to load multiple .env files or load .env from parent directory in Laravel 6

For a Laravel app using docker-compose I have the following (simplified) folder structure:

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

Docker-compose is set up to load database connection details from the .env file in the root folder of the project when constructing the containers. Laravel also needs these and I have to duplicate them in the .env file inside the laravel folder.

I would like to avoid this duplication. Ideally I would load both .env files in Laravel to avoid cluttering up the docker-compose .env with stuff that is only relevant to Laravel. But I would be almost as happy to just have the one .env file in the project root, provided there is a clean way to do it.

I have found no configuration setting but relevant methods loadEnvironmentFrom() and useEnvironmentPath() inside the Illuminate\Foundation\Application but I'm not sure where to call them from. I would extend Application, but it seems that Dotenv is already loaded by the time it is instantiated in /boostrap/app.php

Hopefully there is somewhere outside of the vendor dolder where I could change the path or load a different .env file in time for it to be used by the configuration files. Help is greatly appreciated

Upvotes: 0

Views: 3168

Answers (1)

user12958509
user12958509

Reputation:

Use useEnvironmentPath() in bootstrap/app.php:

$app->useEnvironmentPath($env_path);

Or as a solution:

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

__DIR__ returns full path of current file (since you are in bootstrap/app.php)
dirname(__DIR__, 2), goes back 2 steps form your file location (In your case, it returns your Project directory path)

Now Laravel should read your new .env file.

-- UPDATE --

For HTTP applications, update 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);
    }

And for console applications, edit 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);
    }

And app/Providers/AppServiceProvider.php:

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

Upvotes: 3

Related Questions