Laravel - custom .env file

前端 未结 6 1855
难免孤独
难免孤独 2020-12-31 19:41

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 f

相关标签:
6条回答
  • 2020-12-31 20:06

    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.

    0 讨论(0)
  • 2020-12-31 20:07

    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

    0 讨论(0)
  • 2020-12-31 20:10

    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

    0 讨论(0)
  • 2020-12-31 20:17

    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

    0 讨论(0)
  • 2020-12-31 20:22

    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);
    
    0 讨论(0)
  • 2020-12-31 20:23

    I have similar requirements during development, and wanted to do some ad-hoc 'multitenancy' on my dev box to test the same codebase against multiple databases/configurations. I didn't want spaghetti code with a bunch of if/then statements, so I came up with the following solution, which works great for my purposes (and doesn't require any mucking about with Apache, nginx or Caddy files):

    Add the following in bootstrap/app.php right after the $app = new Illuminate\Foundation\Application(...); lines:

    // First, check to see if there is a file named '.env'
    // within a subdirectory named '.env.{{HOST_NAME}}
    //
    if (is_file($app->environmentPath().DIRECTORY_SEPARATOR. '.env.' . $_SERVER['HTTP_HOST'] .DIRECTORY_SEPARATOR. '.env')) {
    
        // ...And if there is, use the directory as the new environment path
        $app->useEnvironmentPath($app->environmentPath().DIRECTORY_SEPARATOR. '.env.'. $_SERVER['HTTP_HOST']);
    }ER['HTTP_HOST']);
    }
    
    // Otherwise,  just use the standard .env file as the default...
    

    Once this is included, the app will still use .env by default (meaning you can still use the standard .env file for any hosts that don't require customization), but first it checks to see if an alternative .env file exists within a subdirectory named after the hostname (ie, if the hostname is 'example.local.com', the file would reside within a subdirectory named .env.example.local.com).

    You could change the code to remove the somewhat redundant .env. prefix from the directory name, but I like to add it to keep all the .env.* entries together in directory listings.

    One bonus of this approach: By using the usual name ('.env') within subdirectories, you should only need a single entry of .env to ensure all your custom configurations stay out of your git repo. No need to add a new .gitignore entry for each custom dot-env file.

    0 讨论(0)
提交回复
热议问题