在 Laravel 6 中,环境变量的覆写实现的变通方案(env()、config())
1、在生产环境中遇见一个 Bug,当一个容器全新部署后,在第一次运行时,其环境变量的取值,感觉并非容器的环境变量,而是 null。在第二次运行时,其环境变量的取值才正确。在第一次运行时,导致 CDN 请求响应 403。如图1
2、由于容器的环境变量允许覆写,其大致实现流程如下:
(1)从 Vault 获取到某容器的所有环境变量数组
(2)待修改的环境变量合并到第(1)步中获取的环境变量数组中
(3)将新的环境变量数组更新到 Vault
(4)同版本更新容器使环境变量生效
3、环境变量的使用,实际是在 Laravel 的配置文件使用了函数:env()。
'debug' => env('APP_DEBUG', false),
4、在第一次运行时,其环境变量的取值,缓存 $json 为 null,从接口响应 $json 中获取的环境变量,会将环境变量进行覆写。
putenv("{$key}={$value}");
$_ENV[$key] = $value;
5、但是,此时,基于环境变量生成的配置项,即 config 目录下的配置文件,已经被执行了,所以,config 配置项仍然是旧的。
// 主题素材CDN
'theme-asset-cdn' => [
'driver' => 's3',
'key' => env('THEME_ASSET_CDN_AWS_ACCESS_KEY_ID'),
'secret' => env('THEME_ASSET_CDN_AWS_SECRET_ACCESS_KEY'),
'region' => env('THEME_ASSET_CDN_AWS_DEFAULT_REGION', 'us-east-2'),
'bucket' => env('THEME_ASSET_CDN_BUCKET', 'object-theme-assets'),
'root' => env('THEME_ASSET_CDN_ASSET_PREFIX', 'static/xxx/'),
],
6、因此,在第一次运行时,感觉上便像 $json 并未立即被应用至环境变量中。环境变量的覆写实现的变通方案,实际是可通过再次覆写 config() 实现。此时,给用户的感觉便是新的环境变量值已经覆盖了旧的环境变量值。
$newConfig = [
'theme.view_storage' => $json['VIEW_STORAGE'] ?? config('theme.view_storage'),
];
config($newConfig);
7、不过,此方案很是冗余,一旦有新增加的配置项,那么皆需要在 $newConfig 中同步增加相应的配置项。代码实现冗余。尝试替代的方案,基于新的环境变量重新加载配置项。但是,此方案会导致模块目录中的配置项丢失,以及在重新加载之前基于 config()函数自定义的配置项丢失。留待后续完善。如图2
$key = 'THEME_ASSET_CDN_BUCKET';
$value = 'object-theme-assets00';
putenv("{$key}={$value}");
$_ENV[$key] = $value;
config(['theme.view_storage' => 'ss']);
$loadConfiguration = new LoadConfiguration();
$loadConfiguration->bootstrap(app());
Log::debug(
'theme.v2.tenant.manager.1',
[
'env.THEME_ASSET_CDN_BUCKET' => env('THEME_ASSET_CDN_BUCKET'),
'theme.view_storage' => config('theme.view_storage') ?? null,
'theme_asset.versioning' => config('theme_asset.versioning') ?? null,
'theme_asset.cdn_url' => config('theme_asset.cdn_url') ?? null,
'theme_asset.filesystem.disk' => config('theme_asset.filesystem.disk') ?? null,
'filesystems.disks.theme-asset-cdn' => config('filesystems.disks.theme-asset-cdn') ?? null,
]
);
[2023-03-21 18:08:56] local.DEBUG: theme.v2.tenant.manager.1 {
"env.THEME_ASSET_CDN_BUCKET": "object-theme-assets00",
"theme.view_storage": "database",
"theme_asset.versioning": null,
"theme_asset.cdn_url": null,
"theme_asset.filesystem.disk": null,
"filesystems.disks.theme-asset-cdn": {
"driver": "s3",
"key": "111111111111",
"secret": "22222222222",
"region": "us-east-2",
"bucket": "object-theme-assets00",
"root": "static/xxx/"
}
}


近期评论