我在启动Phoenix服务器时试图从Mac中加载API密钥作为系统ENV。我出了什么问题?这些是我的步骤:
-
在我的Mac终端上:
export API_NOTIFICATION_KEY=1234
-
在我的config.exs
中config :app, App.Notifications, notification_api_key: {:system, "API_NOTIFICATION_KEY"}
-
在我使用的模块中
@api_notification_key Application.get_env(:app, App.Notifications)[:notification_api_key]
-
启动我的凤凰服务器
mix phx.server
然后,当我尝试使API调用时,它显示为零。我是否缺少一个步骤来正确加载它?
属性在汇编过程中评估,因此:
@api_notification_key Application.get_env(:app, App.Notifications)[:notification_api_key]
将在编译时设置其值。我认为这不是您想要的,因此最好使用功能:
defp api_notification_key() do
case Application.get_env(:test, App.Notifications)[:notification_api_key] do
{:system, var_name} -> System.get_env(var_name)
value -> value
end
end
当我使用您的配置时,请尝试使用以下方式访问控制器中的密钥
Application.get_env(:app, App.Notifications)[:notification_api_key]
我得到:
{:system, "API_NOTIFICATION_KEY"}
因此,凤凰城没有查找Env变量。另一方面,如果我手动在配置中设置键,则是这样的:
config :app, App.Notifications,
notification_api_key: 1234
然后我在控制器中获得1234
。我读了一些内容,这些内容在某个时候会弃用{:system, "ENV_VAR"}
的阅读环境变量,并且在文档中没有提及:system
。我正在使用phoenix 1.4.6
。
根据本文,您可以在endpoint.ex
中定义init/2
函数,该功能将在运行时称为 - 仅在Phoenix应用程序开始之前,这意味着您可以在运行时间直接查找环境变量,该变量在运行时使用System.get_env/1
。phoenix.endpoint文档中描述了init/2
功能:
动态配置
用于动态配置端点,例如从 环境变量或配置文件,Phoenix调用 端点上的init/2回调,通过A:主管原子作为第一个 参数和端点配置为第二。
这是我想到的一个例子:
def init(:supervisor, config) do
#IO.inspect config, label: "config"
#IO.inspect Application.get_all_env(:app1), label: "all"
Application.put_env(:app1, :notification_api_key,
System.get_env("API_NOTIFICATION_KEY"),
persistent: true
)
{:ok, config}
end
然后在我的控制器中:
key = Application.get_env(
:app1, App1.Notifications
)[:notification_api_key]
IO.inspect key, label: "key"
,在服务器窗口中我看到:
key: 1234
您还应该意识到设置模块属性发生在编译时间,因此该行:
@api_notification_key Application.get_env(:app, App.Notifications)[:notification_api_key]
检索编译应用程序的系统的ENV变量。
我还尝试在控制器中设置模块属性:
@attr Application.get_env(
:app1, App1.Notifications
)[:notification_api_key]
和 init/2
在endpoint.ex中定义为上述,在我的控制器@ATTR中,nil nil nil nil nil nil nil nil nil。这是因为在编译时,尚未调用init/2
,因此尚未设置:notification_api_key
的值。
对我来说,在init/2
中打电话给Application.put_env()
不正确:
def init(:supervisor, config) do
Application.put_env(:app1, :notification_api_key,
System.get_env("API_NOTIFICATION_KEY"),
persistent: true
)
{:ok, config}
end
我认为我应该对config
做些事情。这是另一个例子:
def init(:supervisor, config) do
IO.inspect config, label: "config"
key = System.get_env("API_NOTIFICATION_KEY")
new_config = Keyword.put_new(config, :notification_api_key, key)
IO.inspect new_config, label: "inside init/2: new_config"
{:ok, new_config}
end
然后在我的控制器中:
IO.inspect(
App1Web.Endpoint.config(:notification_api_key, :not_set),
label: "config"
)
在我的服务器窗口中,我看到:
config: "1234"
也有效。