Symfony 4、.env文件和生产环境

5

.env文件在Docker、Kubernetes等技术中非常方便。

但是,如果我只有一个简单的nginx服务器,没有任何编排工具,还有一堆cron worker和一堆守护进程(systemd/supervisord等),该怎么办呢?
我可以将这些环境变量写入nginx服务器部分,但是我必须为每个cron worker或守护进程设置数百个环境变量。

我找到了一个快速解决方案:在生产中使用symfony/dotenv组件。
但是这似乎很不好。谁能提供更好的解决方案呢?


这是一个非常好的问题,因为并不是每个人都可以访问服务器配置,因此Symfony 4在通过FTP部署时可能会很困难。我看到现在有很多人在生产中使用dotenv。 - Thomas Decaux
我有访问权限,但服务器上有不同的应用程序(在一个用户内),我无法使用全局或用户环境变量。 - Dmitry
实际上,Symfony缺少像Docker一样的“--env-file”选项!在执行sf console之前,您可以通过执行“export $$(grep -v '^#' .env | xargs)”从文件中导出环境变量。 - Thomas Decaux
2个回答

11
首先,并不是所有变量都需要使用环境变量来指定。将那些在每个系统上都相同的变量放在一个单独的yaml文件中。
当您只有一个服务器环境时,可以在`/etc/environment`中全局指定环境变量。(根据您的Linux版本可能会有所不同)
就我个人而言,当您在同一台服务器上运行多个环境时,使用DotEnv会带来更多的困难而非解决方案。在全局配置中指定变量,如`/etc/environment`,在这种情况下无法工作。
在nginx中指定环境变量也不是解决办法,因为正如您提到的,它们不能被cron、supervisor、控制台等拾取。对我而言,这就是完全删除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文件存在,导入操作将被忽略。另一种解决方案是在Kernel类的configureContainer()中添加一行:

这样,当不存在parameters.yaml文件时,导入操作将被忽略。另一个解决方法是在您的Kernel类的configureContainer()中添加一行:
$loader->load($confDir.'/parameters'.self::CONFIG_EXTS, 'glob');

谢谢你的回答。是的,我的环境列表只包含在服务器上不同的变量。此外,我们每个服务器上有6个项目(来自一个系统),它们将具有不同的凭据,因此我们不能使用/etc/environment。我们在docker中进行测试,所以yaml文件对它来说并不方便。 - Dmitry
通过上述解决方案,您只需要在生产环境中有一个parameters.yaml文件。在测试环境中,您仍然可以继续使用.env文件。 - Sander Toonen

2

如果您想为cli和fpm集中管理环境变量,您可以在系统中定义它们一次,然后在您的php-fpm.conf中引用它们:

....
[www]
env[APP_VAR1] = $APP_VAR1
env[APP_VAR2] = $APP_VAR2
...

这样,您可以避免在生产环境中使用DotEnv,这是最佳实践所鼓励的。

希望这有所帮助。


1
你所谈论的是Web服务器,而问题是关于Linux命令行界面(如CRON)的。 - Thomas Decaux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接