dotenv requires .env file on production

Sander Visser picture Sander Visser · Jun 4, 2015 · Viewed 25.8k times · Source

I'm using dotenv for PHP to manage the environment settings (not lavarel but I tagged it because lavarel also uses dotenv)

I have excluded the .env from the code base and I have added the .env.example for all other collaborators

On the github page of dotenv:

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.

The thing that I don't understand is that I get the following exception:

PHP Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Dotenv: Environment file .env not found or not readable.

This contradicts with what documentation says "the actual environment variables should be set so that there is no overhead of loading the .env file on each request."

So the question is if there's any reason why dotenv throws that exception and/or am I missing something? First of all the behavior is different compared to other dotenv libraries (ruby)

I can easily work around this, the not so nice solution:

if(getenv('APPLICATION_ENV') !== 'production') { /* or staging */
    $dotenv = new Dotenv\Dotenv(__DIR__);
    $dotenv->load();
}

Nicest solution in my opinion, but I think dotenv should handle this.

$dotenv = new Dotenv\Dotenv(__DIR__);
//Check if file exists the same way as dotenv does it
//See classes DotEnv\DotEnv and DotEnv\Loader
//$filePath = $dotenv->getFilePath(__DIR__); 
//This method is protected so extract code from method (see below)

$filePath = rtrim(__DIR__, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR . '.env';
//both calls are cached so (almost) no performance loss
if(is_file($filePath) && is_readable($filePath)) {
    $dotenv->load();
}

Answer

Alik picture Alik · Jun 4, 2015

Dotenv was built around an idea, that it will be used in development environments only. Thus, it always expects .env file to be present.

The solution you didn't like is a recommended way to use Dotenv. And it seems, that it won't change in near future. Related discussion in project's issue tracker: https://github.com/vlucas/phpdotenv/issues/63#issuecomment-74561880

Note, that Mark offers there a good approach for production/staging environments, which skips file loading, but not validation

$dotenv = new Dotenv\Dotenv();
if(getenv('APP_ENV') === 'development') {
    $dotenv->load(__DIR__);
}
$dotenv->required('OTHER_VAR');