Home » Php » php – Laravel – custom .env file

php – Laravel – custom .env file

Posted by: admin July 12, 2020 Leave a comment

Questions:

Laravel assumes that .env file should describe environment, and it should not be committed to your repo.

What if I want to keep both .env files for dev and production (say .env-production and .env-dev) in my repo and add some custom logic to which file should be used, for example based on current domain name.

Something like

if ($_SERVER['HTTP_HOST'] == 'prod.domain.com') {
    load('.env-production');
} else {
    load('.env-dev');
}

How can i achieve it?
Thanks!

How to&Answers:

Nadeem0035 gave me pretty good idea what to do

bootstrap\app.php right before return $app;

$envFile = $_SERVER['HTTP_HOST'] == 'prod.domain.com' ? '.env-production' : '.env-dev';
$app->loadEnvironmentFrom($envFile);

Answer:

Use Dotenv::load() for custom .env file

laravel 5.1 with vlucas/phpdotenv ~1.0

if ($_SERVER['HTTP_HOST'] == 'prod.domain.com') {
    Dotenv::load(__DIR__ . '/../','.production.env');
} else {
    Dotenv::load(__DIR__ . '/../','.dev.env');
}

OR

laravel 5.2 with vlucas/phpdotenv ~2.0

$dotenv = new Dotenv\Dotenv(__DIR__, 'myconfig'); // Laravel 5.2
$dotenv->load();

PHP dotenv

In bootstrap/app.php

Answer:

I like to add a solution for people who have a shared codebase for many vhosts that all need different .env files for all the different things, like database connections, smtp settings etc.

For every vhost, on Apache, create a vhost config:

<VirtualHost *:80>
    ServerName your-vhost.yourdomain.com
    DocumentRoot /var/www/shared-codebase/public

    SetEnv VHOST_NAME 'your-vhost'

    <Directory "/var/www/shared-codebase/public">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride all
    Order deny,allow
    Require all granted
    </Directory>

    <IfModule mpm_itk_module>
       AssignUserId your-vhost your-vhost
    </IfModule>

    ErrorLog /var/www/your-vhost/logs/error.log
    CustomLog /var/www/your-vhost/logs/access.log combined
</VirtualHost>

All vhosts have the same document root and directory, because it is a shared codebase. Inside the config we added a SetEnv VHOST_NAME 'your-vhost' which we will later use in Laravel’s bootstrap.php to change the location of vhost specific .env.

Next create the custom .env file in a folder(fe. /var/www/your-vhost/.env) the alter bootstrap.php so that it loads the .env from the right location.

<?php

$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

/*
|--------------------------------------------------------------------------
| Add the location of the custom env file
|--------------------------------------------------------------------------
*/    
$app->useEnvironmentPath('/var/www/'.$_SERVER['VHOST_NAME']);

return $app;

That’s all.

[edit]
I you want to target a specific database or want to generate a key for a specific .env, then you should put the VHOST_NAME in front of the artisan command.

VHOST_NAME=tenant2.domain.com php artisan key:generate

[edit]
When working locally and are using Laravel Valet, then you can add a custom .valet-env.php in the root of your codebase.
https://laravel.com/docs/master/valet#site-specific-environment-variables

Answer:

You’ve single .env file into laravel and you can define level of your app.

APP_ENV=local

OR

APP_ENV=production

You can set configuration as per your requirement and not need to create new .env file to here. More about Laravel Environment Variables :
and Here’s more descriptive help for you: phpdotenv

Answer:

I’d like to share my two cents on this, for team working on different machines / hosts.
I create a directory env on app’s root, containing:

  • a .master.env file with the main and shared configuration.
  • a .name file containing only a string with the environment’s name for specific machine / purpose (e.g. “server1”)
  • the specific .env file matching the name defined above, e.g. .server1.env.

Then, in bootstrap/app.php:

/**
 * master config
 */
$app->useEnvironmentPath(__DIR__.'/../env');
$app->loadEnvironmentFrom('.master.env');

/**
 * config overloading
 */
$app->afterLoadingEnvironment(function() use($app) {
    $envFile = trim(file_get_contents($app->environmentPath().'/.name'));
    if ($envFile && file_exists($app->environmentPath().'/.' .$envFile .'.env')) {
        $dotenv = Dotenv\Dotenv::create($app->environmentPath(), '.'.$envFile.'.env');
        $dotenv->overload();
    }
});

Now you can selectively override configuration keys for specific machines and if you don’t have security issues you can put the env files in VCS , as long as you ignore the `.name’ file.

Working in Laravel 5.8.