Environments management
samdark opened this issue · comments
I'd use https://github.com/vlucas/phpdotenv for handling it.
Usage example:
- https://github.com/dmstr/phd5-app/blob/master/web/index.php#L6 (included right after autoloading)
- https://github.com/dmstr/phd5-app/blob/master/src/config/env.php
- https://github.com/dmstr/phd5-app/blob/master/src/app.env-dist
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 :)
Exclude environment variables from logging: https://github.com/dmstr/phd5-app/blob/master/src/config/common.php#L132-L142
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.
Another implementation: https://github.com/symfony/dotenv
@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.