在 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/" } }
近期评论