0

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

1 Answer 1

3

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));
}
Sign up to request clarification or add additional context in comments.

2 Comments

Unfortunately, this only half works. That is to say artisan loads the correct .env file and I can run migrations and seeds and queries on through tinker; but when I request a route, any route, over HTTP I either get a db connect error, or if the route doesn't involve a db query, an unresolvable missing app key error, which indicates the .env is not being loaded.
After further testing I realized that the reason your original solution was working with artisan and not over HTTP was because the apache container had the laravel directory mapped to /var/www/html and had no access to the parent directory 🤦‍♂️. I realized this when I tried running the project locally where your solution works fine. So I've selected your answer as correct since it does do what I asked for, but it's looking like I will probably end up configuring docker to read the env file from the laravel directory instead of using your solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.