yiisoft / yii-base-web

Home Page:https://www.yiiframework.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Environments management

samdark opened this issue · comments

Usage example:

Please do not name the ENV file .env in the root project folder, since this would conflict with docker-compose.

Personally I put gitignored .env and .env.example into config directory. Getting variables style is similar to yours i.e. getenv().

I prefix variable names with project ID such as BCM_DB_USERNAME.

Personally I put gitignored .env and .env.example into config directory.

Technically this would make no problems, but...

My point regarding a name different from .env, is just about trying the confusing the user less (when using docker-compose). Sure, this comes from my Docker point of view, but I think we could apply that for all apps (more explanations can be found here).

Actually, while I wanted to link to https://github.com/direnv/direnv - as an example for another usage.
I realized that we will rename the file anyway, so it'll be fine.


What I actually wanna say is, that there should be a "env" file for your "control environment" in the top level, which might contain variables like COMPOSE_PROJECT_NAME, MYSQL_ROOT_PASSWORD or GITHUB_API_TOKEN, which are not required for the application to run, but only for setup or local development.

The file (config/app.env.example) contains all the ENV variables defined (or used) by the application, along with their default setting. [Example from phd5]

TL;dr

.env.example
config/app.env.example

I prefix variable names with project ID such as BCM_DB_USERNAME.

We do that for newly introduced variables, the ones from the template are prefixed with APP_; we are using the "service" in general as a prefix, like:

  • DB_
  • REDIS_
  • AMAZON_
  • FTP_

(DB_ should actually be MYSQL_ when thinking about it)

I'm doing so because I'm running multiple projects at the same server w/o any containers.

But all your projects share the credentials of all the other projects via ENV variables then?

Almost. I'm still using .env at the server so nope but noone should do it like that :)

Config must be diferrent formats: yml, php, ini etc. Env it's only ini.
Best solutions:
https://github.com/zendframework/zend-config
https://github.com/symfony/config

For small projects env is most suitable but not middle and big projects

Config generator should be independed component

.env isn't going to replace regular configs. It's a source of values that were, in case of advanced app, stored in -local.php environment-dependent configs.

@samdark how can i configure different log targets for different environments with env?
For example in production i need write log to files and sentry, in local i need write log in files.
This is a popular task.

Variant 1:

$loggerConfig = [
    'traceLevel' => getenv('LOG_TRACE_LEVEL'),
    'targets' => [],
];

if (getenv('LOG_ENABLE_FILE_TARGET')) {
    $loggerConfig['targets'][] = [
        'class' => 'yii\log\FileTarget',
       // ...
    ];
}

return $loggerConfig;

Variant 2:

'components' => [
    'log' => [
        'targets' => getenv('IS_PRODUCTION') ? require 'production.log.php' : require 'development.log.php';
    ]
]

Variant 3:

Use -local.php files and place correct ones at the server at deploy.

And i need to use local config php files :) Why .env?

Ok, second popular task. How can i configure local queue driver? Again use local php files.
Configuration in production can be very different. Sysadmins often changes configs. For example need to change beanstalk to rabbit and they should wait programmers fix config.
This limits us

.env as file is for development purposes mainly. In production you'd use containers or set variables via nginx config or something like that. It depends very much on the toolset used but environment variables are quite common. See https://12factor.net/config

I prefer as a more flexible dotenv: https://github.com/josegonzalez/php-dotenv
Also it has explicit syntax specs depending on https://github.com/m1/env .

I think processing and loading configuration is rather complex task.
And I'm afraid it is rather controversial and holy-war prone topic.
At the moment we at Yii-team agreed on use of composer-config-plugin.
This solution is recommended but not obligatory to use.
Every developer is free to choose how he prefers his application config to be prepared and loaded.
Also we've made all configs more easy to use by providing it explicitly in config folder of every Yii extension.

This plugin performs complex process of assembling whole config stack:

  • environment variables, including .env file (with vlucas/phpdotenv)
  • PHP constant definitions
  • params
  • any number of configurations: common, web, console, tests, ...

Pros of this solution:

  • allows every extension provide it's recommended config - which allows easier use of extensions
  • assembles all configs in single quickly loadable PHP file (no need to merge configs on every request to application)
  • supports JSON and YAML configurations (anything else can be implemented too)
  • provides means to debug assembled configuration which becomes very important for big applications with lots of extensions

Here is how entry script looks when the plugin is used:
https://github.com/yiisoft/yii-project-template/blob/master/public/index.php

use hiqdev\composer\config\Builder;
use yii\di\Container;
use yii\helpers\Yii;

(function () {
    require_once __DIR__ . '/../vendor/autoload.php';
    $container = new Container(require Builder::path('web'));
    Yii::setContainer($container);
    $container->get('app')->run();
})();

Single line require Builder::path('web') does:

  • loads environment variables,
  • defines PHP constants (according to environment vars),
  • sets parameters (according to env.vars and constants),
  • returns configuration (according to env.vars, constants and params)

You can read more about use of the composer-config-plugin at it's README.
Also you can read about more global idea behind the plugin here: https://hiqdev.com/pages/articles/app-organization

So, "environments management" is implemented. Closing this issue.
Please open a new issues with more specific questions.