Reloading .env variables without restarting server (Laravel 5, shared hosting)
Asked Answered
G

9

58

My Laravel 5 has run OK until the database was configured, then found this error:

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

Doing some research it seems that I configured MySQL access too late, so I should restart the server in order to get the correct environment variables. Well, I'm using Dreamhost's shared server and I just can't do that.

How should I fix this issue?

Thanks

Gastelum answered 6/9, 2015 at 11:26 Comment(2)
You don't have to restart webserver in order to make Laravel reread it's .env file. Laravel does it during every run.Glasgo
@max.lanin so then if that's not the problem, if the credentials are correct, what is the problem? I'm running php artisan migrate so that I apply the migrationGastelum
G
-11

In config/database.php I changed the default DB connection from mysql to sqlite. I deleted the .env file (actually renamed it) and created the sqlite file with touch storage/database.sqlite. The migration worked with sqlite.

Then I switched back the config/database.php default DB connection to mysql and recovered the .env file. The migration worked with mysql.

It doesn't make sense I guess. Maybe was something serverside.

Gastelum answered 7/9, 2015 at 16:15 Comment(1)
Even though it solved your problem, you shouldn't mark a "hack" as an answer - it encourages bad practicesEgerton
B
116

If you have run php artisan config:cache on your server, then your Laravel app could cache outdated config settings that you've put in the .env file.

Run php artisan config:clear to fix that.

Bollay answered 28/12, 2016 at 18:30 Comment(1)
Running php artisan config:cache actually clears the cache and rebuilds it, so I'd recommend that instead of just config:clear if you want to keep using the cache. BUT TIL that if you use the env() function outside of the cache files, you'll get NULL values when your config is cached. So make sure to ONLY use env() inside the files in your cache directoryDeplorable
F
41

I know this is old, but for local dev, this is what got things back to a production .env file:

rm bootstrap/cache/config.php

then

php artisan config:cache
php artisan config:clear
php artisan cache:clear
Forwards answered 13/5, 2019 at 13:48 Comment(1)
The docs specifically state "You should typically run the php artisan config:cache command as part of your production deployment routine. The command should not be run during local development"Swop
V
20

It's possible that your configuration variables are cached. Verify your config/app.php as well as your .env file then try

php artisan cache:clear

on the command line.

Vieira answered 6/9, 2015 at 13:40 Comment(3)
Thanks but I already tried that. Anyway, if .env variables override config/app.php variables why should I check this file?Gastelum
They don't. The config/app.php file use them with the env() function. All config files do, really. So I'd check the config/database.php to see if the calls to env() use the correct names.Vieira
Let's see, if I have the app working locally with apache I should only tweak some values in the .env file in the server, right? And if nothing is changed inside the config/files everything should be working I guess. There's something I'm missing damnGastelum
A
18

To be clear there are 4 types of caches you can clear depending upon your case.

php artisan cache:clear

You can run the above statement in your console when you wish to clear the application cache. What it does is that this statement clears all caches inside storage\framework\cache.

php artisan route:cache

This clears your route cache. So if you have added a new route or have changed a route controller or action you can use this one to reload the same.

php artisan config:cache 

This will clear the caching of the env file and reload it

php artisan view:clear 

This will clear the compiled view files of your application.

For Shared Hosting

Most of the shared hosting providers don't provide SSH access to the systems. In such a case you will need to create a route and call the following line as below:

Route::get('/clear-cache', function() {
    Artisan::call('cache:clear');
    return "All cache cleared";
});
Against answered 12/4, 2019 at 16:1 Comment(0)
G
7

A short solution:

use Dotenv;

with(new Dotenv(app()->environmentPath(), app()->environmentFile()))->overload();
with(new LoadConfiguration())->bootstrap(app());

In my case I needed to re-establish database connection after altering .env programmatically, but it didn't work , If you get into this trouble try this

app('db')->purge($connection->getName()); 

after reloading .env , that's because Laravel App could have accessed the default connection before and the \Illuminate\Database\DatabaseManager needs to re-read config parameters.

Greenland answered 11/5, 2018 at 9:31 Comment(2)
It works but I had to use these two imports: use Dotenv\Dotenv; use Illuminate\Foundation\Bootstrap\LoadConfiguration;Alfano
When it comes to the database DB::reconnect(); did the trick.Alfano
C
3

In case anybody stumbles upon this question who cannot reload their webserver (long running console command like a queue runner) or needs to reload their .env file mid-request, i found a way to properly reload .env variables in laravel 5.

use Dotenv;
use InvalidArgumentException;

try {
    Dotenv::makeMutable();
    Dotenv::load(app()->environmentPath(), app()->environmentFile());
    Dotenv::makeImmutable();
} catch (InvalidArgumentException $e) {
    //
}
Charlean answered 15/9, 2017 at 10:11 Comment(1)
my laravel doesn't seem to be able to import Dotenv by defaultEustacia
D
1

This is the only question I could find relating to reloading .env and thus config($key) values on an existing app instance, but many of these answers should probably live on a different question.

I got the following to work for a Laravel 6.x application, while trying to make an artisan command use my cypress environment variables.

For context $this->laravel === app().

    /**
     * Make the application use the cypress environment variables
     *
     * @return void
     */
    protected function enableCypressEnv()
    {
        // Get all of the original values from config. We need to do this because
        // rebuilding config will skip packages.
        $old = app(Repository::class)->all();

        // Change the applications env file
        $this->laravel->loadEnvironmentFrom('.env.cypress');

        // Reload the app's environment variables 
        Dotenv::create(
            $this->laravel->environmentPath(),
            $this->laravel->environmentFile(),
            Env::getFactory()
        )->overload();

        // Force config to be rebuitl with new env
        (new LoadConfiguration())->bootstrap($this->laravel);
        
        // Get all of the new values from buidling with new env
        $new = app(Repository::class)->all();

        // Merge the new values over the old distinctly
        $merged = array_merge_recursive_distinct($old, $new);

        // Get the applications configuration instance
        $config = config();

        // Overwrite all of the values in the container in accordance with the merged values
        foreach ($merged as $key => $value) {
            $config->set([$key => $value]);
        }
    }

Shoutout to the answers above for pointing me in the right direction, but I will include my answer here as none of them worked perfectly for me.

Deledda answered 2/11, 2021 at 23:8 Comment(1)
If you are wondering why one might want to do this, I have created the ability for cypress to access config file values by exporting them to a json file. Obviously this file will need to be built with the correct .env values configured. Since I will often be running this locally, I don't want to have to constantly rename my .env values, instead I can just let the command do it for me.Deledda
M
0

A variant of existing answer, including DB reload, tested and working on Laravel 10:

use Illuminate\Support\Env;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
use Dotenv\Dotenv;

$start_connection = env('DB_CONNECTION');
app()->loadEnvironmentFrom('.env.myotherenv');
Dotenv::create(Env::getRepository(), app()->environmentPath(), app()->environmentFile())->load();
(new LoadConfiguration())->bootstrap(app());
app('db')->purge($start_connection);

Here more details.

Montford answered 26/3 at 10:54 Comment(0)
G
-11

In config/database.php I changed the default DB connection from mysql to sqlite. I deleted the .env file (actually renamed it) and created the sqlite file with touch storage/database.sqlite. The migration worked with sqlite.

Then I switched back the config/database.php default DB connection to mysql and recovered the .env file. The migration worked with mysql.

It doesn't make sense I guess. Maybe was something serverside.

Gastelum answered 7/9, 2015 at 16:15 Comment(1)
Even though it solved your problem, you shouldn't mark a "hack" as an answer - it encourages bad practicesEgerton

© 2022 - 2024 — McMap. All rights reserved.