我是 AWS 部署新手,并且我的 Elixir/Phoenix 应用程序遇到问题。
我已将应用程序部署到 AWS ECS,但遇到环境变量问题。
prod.exs
中使用System.get_env()
从环境变量中获取值的所有配置都会返回nil
。
在我的
prod.exs
文件中:
config :my_app, :my_variable, System.get_env("MY_VARIABLE")
...
在我的模块中:
defmodule MyApp.MyModule do
@my_variable Application.compile_env(:my_app, :my_variable)
def get_variable, do: Application.get_env(:my_app, :my_variable)
...
end
这两个方法都会返回
nil
。
但是,奇怪的是,
System.get_env("DATABASE_URL")
中的runtime.exs
工作正常(如果没有数据库连接,该应用程序将无法运行)。这表明应用程序可以读取任务定义中定义的环境变量。
现在,我对运行时和编译时如何处理环境变量感到困惑。对于我的情况,如何解决这个问题?我应该在哪里放置我的配置?我什么时候应该注入编译时环境变量?
我是否应该将所有配置移至
runtime.exs
并停止使用Application.compile_env/2
?
请帮助我。
请记住,
prod.exs
和特定于环境的配置文件是在构建时(即编译应用程序时)执行的。通常在部署管道中,这发生在单独的构建机器上(例如,作为 Github 工作流程的一部分)。该机器上设置的环境变量可能与应用程序最终运行的机器上设置的任何环境变量无关。
我的建议是使用 System.fetch_env!/1
和其他 bang 函数来读取环境变量 - 如果出现问题,它们会立即提醒您,并帮助您进一步解决此问题。我是
dotenvy 的作者,旨在帮助减少读取环境变量时产生的混乱。该包可能对您有用,也可能没用,但了解其背后的推动力有助于在部署应用程序时进行思考。我写了几篇文章来进一步思考与您的问题相关的微妙之处:https://fireproofsocks.medium.com/configuration-in-elixir-with-dotenvy-8b20f227fc0e
要点是深入研究您的应用程序如何读取环境变量,尤其是。编译时与运行时。与其他编译时配置文件相比,利用runtime.exs
有几个优点,但这只是许多有效的配置方法之一。我喜欢它,因为它使应用程序与其环境的契约更加明确,并且避免了使用配置提供程序等内容的不透明性,但任何应用程序都有许多因素可能会建议哪种配置策略最适合。