How to have environment specific .env files for dotenv (in Laravel 5)

16,013

Solution 1

Solved it in the end by modifying app/Providers/ConfigServiceProvider.php. This file is added as a stub to your app folder when you create a project and is intended for overriding config values.

It now handles the cascading configs, so that any values in config/local/app.php for example will override config/app.php. As the comment below says it doesn't handle matching arrays in the environment config and will just replace then. But I can solve that when I need it.

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Symfony\Component\Finder\Finder;

class ConfigServiceProvider extends ServiceProvider {

    /**
     * Overwrite any vendor / package configuration.
     *
     * This service provider is intended to provide a convenient location for you
     * to overwrite any "vendor" or package configuration that you may want to
     * modify before the application handles the incoming request / command.
     *
     * Modified 2014-01-20 to allow environment specific configs to be loaded
     * from app/config/[environment]/ which will cascade over the base configs.
     *
     * @return void
     */
    public function register()
    {
        $config = app('config');
        $envPath = app()->configPath() . '/' . getenv('APP_ENV');

        foreach (Finder::create()->files()->name('*.php')->in($envPath) as $file)
        {
            $configName = basename($file->getRealPath(), '.php');
            $oldConfigValues = $config->get($configName);
            $newConfigValues = require $file->getRealPath();

            // Replace any matching values in the old config with the new ones.
            // Doesn't yet handle matching arrays in the config, it will just replace them.
            $config->set($configName, $newConfigValues + $oldConfigValues);
        }
    }

}

Solution 2

You dont have to use .env for everything. There are a few options.

Option 1 - Use only .env for a variable

'default' => env('DB_CONNECTION'),

Option 2 - Use only .env for a variable, but have a system default if none exists

'default' => env('DB_CONNECTION', 'mysql'),

Option 3 - just hard code your variable and not make it settable via the .env

'default' => 'mysql',

Option 2 is probably the best for most config options. You still define (and commit) an option for your config to your git repo - but you can easily override it in any .env file in the future if you want.

Option 1 is best specifically for passwords, app keys etc - so they are never committed to your git repo.

Option 3 is for a few config variables which you know will just never change.

Note - the cascading Laravel 4 config folder option is no longer available.

Solution 3

It is easy to configure Laravel 5 environment.

  1. Open your root application folder and find ".env.example",
  2. Copy and rename into ".env",
  3. Please fit ".env" file into your environment,
  4. If you use GIT, make sure you don't push this file to your GIT repository.

For 'complete explanation', I write this configuration here.

I quote from the dotenv developer;

phpdotenv is made for development environments, and generally should not be used in production. In production, the actual environment variables should be set so that there is no overhead of loading the .env file on each request. This can be achieved via an automated deployment process with tools like Vagrant, chef, or Puppet, or can be set manually with cloud hosts like Pagodabox and Heroku.

Share:
16,013

Related videos on Youtube

Gnuffo1
Author by

Gnuffo1

Updated on June 22, 2022

Comments

  • Gnuffo1
    Gnuffo1 almost 2 years

    I've just started using Laravel 5 which uses the dotenv library. This uses a .env file in the root of the project which sets the environment with this line:

    APP_ENV=local
    

    According to everything I've read on the subject, all other environmental specific configuration should be placed in this file, so database passwords, urls etc, which are then read into the main config array like this:

    env('DB_HOST', 'localhost')
    

    While I feel this may work for a few specific things like database passwords that you might not want committed, what I really want is to be able to commit most or all of my different environmental values for each environment.

    Thus what I want is for .env to define APP_ENV as "local", "staging" or "production" and then have a .local.env or .env.local file containing the values, which I can then commit and the correct file will be loaded based on APP_ENV.

    Is this possible? Laravel 4 had the cascading config arrays which seemed a lot more flexible but if I can have an environmental .env file then I can live with that.

  • user2094178
    user2094178 about 9 years
    The OP is asking how to have an individual .env file for each environment, such as development, testing and production.
  • user3851143
    user3851143 about 9 years
    I updated my answer (Added quote from the developer). So, there is just one .env per machine. And in production, you should not use .env file.
  • Nana Partykar
    Nana Partykar over 8 years
    I'm working locally on Laravel. Just started. Where can I get .ENV file in my 'laravel' folder.?
  • Sander Visser
    Sander Visser over 8 years
    Indeed you should NEVER have a .production.env but you could have a .specialenv.env which can be copied to .env so that those settings are used.