Symfony 4,.env 文件和生产
Symfony 4, .env files and production
.env 文件对于 docker、kubernetes 等
非常方便
但是如果我有没有任何编排的简单 nginx 服务器和一组 cron worker 和一组守护进程 (systemd/supervisord/etc) 怎么办?
我可以将这些 env 变量写入 nginx 服务器部分,但我必须为每个 cron worker 或守护进程设置数百个 env 变量。
我找到了一个快速的解决方案:在生产中使用 symfony/dotenv 组件。
但在我看来很脏。谁能提出更好的解决方案?
首先,并不是所有的变量都需要使用环境变量来指定。将每个系统没有差异的变量保存在单独的 yaml 文件中。
当每台服务器只有一个环境时,您可以在 /etc/environment
中全局指定环境变量。 (可能会有所不同,具体取决于您的 Linux 口味)
就我个人而言,当您 运行 在同一台服务器上使用多个环境时,我发现使用 DotEnv 比解决方案更困难。在这种情况下,在 /etc/environment
之类的全局配置中指定变量不起作用。
在 nginx 中指定环境变量也不是解决方案,因为正如您所提到的,它们不会被 cron、主管、控制台等获取。对我来说,这就是完全删除的原因DotEnv 并再次使用旧的 parameters.yaml
文件。没有什么能阻止你这样做。
然而,另一种解决方案是在您的开发环境中继续使用 DotEnv,并在生产环境中包含一个单独的 parameters.yaml
。然后你可以定义环境变量如下:
parameters:
env(APP_ENV): prod
env(APP_SECRET): 3d05afda019ed4e3faaf936e3ce393ba
...
包含此文件的一种方法是将以下内容放入您的 services.yaml 文件中:
imports:
- { resource: parameters.yaml, ignore_errors: true }
这样,当 parameters.yaml 文件不存在时,导入将被忽略。另一种解决方案是在内核 class:
中向 configureContainer()
添加一行
$loader->load($confDir.'/parameters'.self::CONFIG_EXTS, 'glob');
如果你想为 cli 和 fpm 集中你的环境变量,你可以在你的系统中定义它们一次。然后在 php-fpm.conf
:
中引用它们
....
[www]
env[APP_VAR1] = $APP_VAR1
env[APP_VAR2] = $APP_VAR2
...
这样您就可以避免在生产中使用 DotEnv,这是最佳实践所鼓励的。
希望对您有所帮助。
.env 文件对于 docker、kubernetes 等
非常方便但是如果我有没有任何编排的简单 nginx 服务器和一组 cron worker 和一组守护进程 (systemd/supervisord/etc) 怎么办?
我可以将这些 env 变量写入 nginx 服务器部分,但我必须为每个 cron worker 或守护进程设置数百个 env 变量。
我找到了一个快速的解决方案:在生产中使用 symfony/dotenv 组件。
但在我看来很脏。谁能提出更好的解决方案?
首先,并不是所有的变量都需要使用环境变量来指定。将每个系统没有差异的变量保存在单独的 yaml 文件中。
当每台服务器只有一个环境时,您可以在 /etc/environment
中全局指定环境变量。 (可能会有所不同,具体取决于您的 Linux 口味)
就我个人而言,当您 运行 在同一台服务器上使用多个环境时,我发现使用 DotEnv 比解决方案更困难。在这种情况下,在 /etc/environment
之类的全局配置中指定变量不起作用。
在 nginx 中指定环境变量也不是解决方案,因为正如您所提到的,它们不会被 cron、主管、控制台等获取。对我来说,这就是完全删除的原因DotEnv 并再次使用旧的 parameters.yaml
文件。没有什么能阻止你这样做。
然而,另一种解决方案是在您的开发环境中继续使用 DotEnv,并在生产环境中包含一个单独的 parameters.yaml
。然后你可以定义环境变量如下:
parameters:
env(APP_ENV): prod
env(APP_SECRET): 3d05afda019ed4e3faaf936e3ce393ba
...
包含此文件的一种方法是将以下内容放入您的 services.yaml 文件中:
imports:
- { resource: parameters.yaml, ignore_errors: true }
这样,当 parameters.yaml 文件不存在时,导入将被忽略。另一种解决方案是在内核 class:
中向configureContainer()
添加一行
$loader->load($confDir.'/parameters'.self::CONFIG_EXTS, 'glob');
如果你想为 cli 和 fpm 集中你的环境变量,你可以在你的系统中定义它们一次。然后在 php-fpm.conf
:
....
[www]
env[APP_VAR1] = $APP_VAR1
env[APP_VAR2] = $APP_VAR2
...
这样您就可以避免在生产中使用 DotEnv,这是最佳实践所鼓励的。
希望对您有所帮助。