Hi Laravel,
I want a functionality like loading different .env files based upon the subdomain
of the website let me give you an example,
I have a domain like https://[subdomain].websitename.com
and on every request i'm extracting the subdomain
from the request url and trying to load the different env files which are stored at the root of the application just aside of .env with the name like .[subdomain].env
for loading the env file i'm using the below code in index.php
$tmp = explode('.', $request->getHost());
$subdomain = count($tmp) === 3 ? current($tmp) : '';
if (empty($subdomain) || realpath(__DIR__ . "/../.{$subdomain}.env") === false) {
die("Sorry, I think you are at wrong place, you shouldn't be here :).");
}
$app->loadEnvironmentFrom(".{$subdomain}.env");
$response = $kernel->handle($request)
$response->send();
$kernel->terminate($request, $response);
here, I have empty .env file which will not have any content inside because i don't want any default environment setup. i want subdomain specific settings for the application which will have different db, email & other settings that's why i have different .[subdomain].env files for each subdomains.
I have tried to see the loaded application setting which will show the correct env file loaded but the values are referenced from the old env which was loaded on the last request so, i thought loadEnvironmentFrom
is not working as expected to work.
index.php
at the end of the file before processing the request.config('app')
.thanks in advance,
Hi!
The loadEnvironmentFrom method is only setting the environment filename you hand over to it. It doesn't load the file directly. This happens in the bootstrapping part of the application by the DotEnv class.
Did you think about handling all that stuff in the bootstrap() method of the Kernel.php file? This would be the right place for it, I think, as this is one of the first places that is being loaded (as stated in the docs under https://laravel.com/docs/5.5/lifecycle ). IMHO the index.php file is the wrong place for that.
A possible solution for your problem:
Set your environment for every subdomain in your webserver vhost, so you don't need to write/extend any php code and just create environment files like eg. .env.subdomain1environment, .env.subdomain2environment, .env.subdomain3environment, ...
For more information please refer to the last paragraph above the blue information box in the docs: https://laravel.com/docs/5.5/configuration#environment-configuration
So, when using Apache2 for example, you could set your environment in your httpd.conf of apache or in your Laravel .htaccess file, with a check for the subdomains you have.
Sample code:
<If "req('Host') == 'sub1.yourdomain.com'">
SetEnv APP_ENV=sub1
</If>
Or
SetEnvIf Host "^sub1\.yourdomain\.com$" APP_ENV=sub1
which will result in filenames like .env.sub1
OR
If the SetEnvIf is not dynamically enough for you and you don't want to specify every single subdomain, you can also try something like this:
SetEnvIf Host "^([^.]*)\.yourdomain\.com$" APP_ENV=$1
which will result in filenames like .env.sub1.yourdomain.com
You can find more information about the possibilities to switch configurations in the following part of the Laravel docs: https://laravel.com/docs/5.6/configuration#environment-configuration
Please have a special look at the blue boxes, there is more information about switching environments based on the APP_ENV environment variable.
I hope this helps. Feel free to ask if you have any further questions.
Best wishes
Tom
For Laravel 5.6, you can do this in public/index.php
I have different DB credentials for different servers; some are live, some are staging, some are dev. This makes it very easy to have a central area for storing configs for all the servers, without getting confused. Still avoid storing this in the repo though!
It also ensures I NEVER overwrite on .env with another incorrect one, destined for a different server.
You can easily adapt this to load for different subdomains.
/*
* Let's make sure we load an environment appropriate for the server the code is running on
*/
$hostname = gethostname();
if (($d = strpos($hostname, '.')) !== false) {
$hostname = substr($hostname, 0, $d);
}
putenv('APP_ENV=' . $hostname);
vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.php checks if APP_ENV is set in line 52, and if it is, the value in APP_ENV is appended to the .env file name in line 57.
So a homestead .env file would be called:
/.env.homestead
My Windows dev server has a Windows name of WINDEV, and the .env filename becomes:
/.env.WINDEV
I've implemented this at bootstrap/app.php just after $app creation:
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
switch(array_shift(explode(".",$_SERVER['HTTP_HOST']))){
case 'sub1':
$app->loadEnvironmentFrom('.env.sub1');
break;
default:
$app->loadEnvironmentFrom('.env');
break;
};
And it works!!!
I've implemented this at bootstrap/app.php just after $app creation:
$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') ); switch(array_shift(explode(".",$_SERVER['HTTP_HOST']))){ case 'sub1': $app->loadEnvironmentFrom('.env.sub1'); break; default: $app->loadEnvironmentFrom('.env'); break; };
And it works!!!
it does not work in Lumen5.6
i try other like this,
my vm or container set environment SERVICE_TAGS
, and my local mac not set it.
``` = php
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
$tag = getenv('SERVICE_TAGS');
if ($tag != null) {
switch($tag){
case 'staging':
$app->loadEnvironmentFrom('./env/.env.staging');
break;
case 'production':
$app->loadEnvironmentFrom('./env/.env');
break;
default:
$app->loadEnvironmentFrom('./env/.env.local');
break;
};
} else {
$app->loadEnvironmentFrom('./env/.env.local');
}
```
Most helpful comment
I've implemented this at bootstrap/app.php just after $app creation:
And it works!!!