Scala:如何使用 Scala 将环境变量加载到 Application.conf 中?
Scala: How to load environment variables into Application.conf using scala?
我有一个 ConfigLoader,我很确定它可以正常工作。我怀疑我没有正确使用 application.conf 文件,或者我的包含 prd.env 和 dev.env 的目录可能不在正确的位置。
我期望发生的事情:
当我输入 sbt run
时,ConfigLoader 读取 application.conf 文件,发现该文件中有变量。然后根据它所处的环境检查 prd.env 或 dev.env,最后加载变量。我想要这个,这样我就可以为 dev 和 prd 使用不同的数据库。
- 我不知道它如何找到包含 prd.env 和 dev.env 的 Meta 目录(见图)。
- 我不知道它如何判断环境是在 dev 还是 prd。
- 现在的目标是部署此应用程序,这就是我需要这些环境变量才能工作的原因。
我真的很感谢所有的帮助,但请尝试详细说明你的答案,因为我真的被困住了,简短的答案通常假设我知道的比我知道的多。谢谢:)
相关技术栈:
- HTTP4S,
- 猫,
- 杜比,
- PostgreSQL
application.conf 文件如下:
appone {
environment = ${ENV}
server-config {
url = ${?BASE_URL}
host = "0.0.0.0"
port = 8080
}
db-config {
driver = "org.postgresql.Driver"
url = ${?DATABASE_URL}
user = ${?APPONE_POSTGRES_USER}
password = ${?PASSWORD}
connection-threads = 4
}
}
Meta/dev.env 文件(我也有一个 Meta/prd.env 但由于内容的原因在这里显示了它)
ENV=dev
BASE_URL=http://localhost:8080/
DATABASE_URL=jdbc:postgresql://localhost:5400/bookswapdb
APPONE_POSTGRES_USER=su
PASSWORD=password
加载配置文件如下:
package com.fullstackryan.appone.config
import cats.ApplicativeError
import cats.implicits._
import pureconfig.error.ConfigReaderException
import pureconfig.{ConfigReader, ConfigSource, Derivation}
import shapeless.the
trait LoadConfig[F[_], TConfig] {
def load: F[TConfig]
}
object LoadConfig {
def load[F[_], TConfig](implicit loadConfig: LoadConfig[F, TConfig]): F[TConfig] =
the[LoadConfig[F, TConfig]].load
def apply[F[_], TConfig](
implicit reader: Derivation[ConfigReader[TConfig]], ae: ApplicativeError[F, Throwable]
): LoadConfig[F, TConfig] =
new LoadConfig[F, TConfig] {
def load: F[TConfig] = ApplicativeError[F, Throwable].fromEither {
ConfigSource.default
.at("appone")
.load[TConfig]
.leftMap(ConfigReaderException(_))
}
}
}
错误
pureconfig.error.ConfigReaderException: Cannot convert configuration to a scala.runtime.Nothing$. Failures are:
at 'appone.db-config':
- (application.conf @ jar:file:/Users/ryanmcavoy/fullStackRyan/appone/target/bg-jobs/sbt_3cc4b1f5/job-11/target/419ddc2c/5befcb57/appone_2.13-0.0.1-SNAPSHOT.jar!/application.conf: 10) Key not found: 'url'.
- (application.conf @ jar:file:/Users/ryanmcavoy/fullStackRyan/appone/target/bg-jobs/sbt_3cc4b1f5/job-11/target/419ddc2c/5befcb57/appone_2.13-0.0.1-SNAPSHOT.jar!/application.conf: 10) Key not found: 'username'.
- (application.conf @ jar:file:/Users/ryanmcavoy/fullStackRyan/appone/target/bg-jobs/sbt_3cc4b1f5/job-11/target/419ddc2c/5befcb57/appone_2.13-0.0.1-SNAPSHOT.jar!/application.conf: 10) Key not found: 'pool-size'.
at com.fullstackryan.appone.config.LoadConfig$$anon.$anonfun$load(LoadConfig.scala:25)
at cats.syntax.EitherOps$.leftMap$extension(either.scala:172)
at com.fullstackryan.appone.config.LoadConfig$$anon.load(LoadConfig.scala:25)
at com.fullstackryan.appone.server.ApponeServer$.$anonfun$stream(ApponeServer.scala:32)
at com.fullstackryan.appone.server.ApponeServer$.$anonfun$stream$adapted(ApponeServer.scala:31)
at fs2.Stream$.$anonfun$flatMap(Stream.scala:1188)
at fs2.internal.FreeC$.go(Algebra.scala:609)
at fs2.internal.FreeC$.$anonfun$flatMapOutput(Algebra.scala:616)
at fs2.internal.FreeC$$anon.cont(Algebra.scala:53)
at fs2.internal.FreeC$ViewL$$anon$$anon.cont(Algebra.scala:242)
at fs2.internal.FreeC$ViewL$.mk(Algebra.scala:231)
at fs2.internal.FreeC$ViewL$.apply(Algebra.scala:220)
at fs2.internal.FreeC.viewL(Algebra.scala:106)
at fs2.internal.FreeC$.go(Algebra.scala:414)
at fs2.internal.FreeC$.$anonfun$compile(Algebra.scala:464)
at fs2.internal.FreeC$.$anonfun$compile(Algebra.scala:430)
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.14")
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10")
addSbtPlugin("au.com.onegeek" % "sbt-dotenv" % "2.1.204")
// deploy heroku
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.6")
addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.0")
当通过 sbt run
运行 时,环境由您 运行 sbt 所在的 shell 设置。定义一个 dev.env
文件本身没有任何作用。
设置sbt所在环境的机制运行会因你的shell而异。
例如,如果 bash 是您的 shell(这在其他与 Bourne 兼容的 shell 中值得尝试),请在环境变量前加上 export
,例如:
export ENV=dev
然后您将从 dev.env
导出的环境变量合并到您的 bash 环境中
source meta/dev.env
然后将设置这些环境变量,从而在您的 shell 会话期间将其合并到您的配置中(即它们将继续跨越多个 sbt run
s 直到您退出 shell).如果您更改 dev.env
,它们将在您再次 source meta/dev.env
之前可用。
看到错误提示 application.conf: Key not found: 'username'
的地方了吗?这意味着它正在那个 application.conf
文件中寻找一些 username
但没有找到它。如果您自己查看 application.conf
文件,您会发现其中确实没有名为 username
的设置。有一个叫做 user
,也许这就是你想要的?
我们也看到 Key not found: 'pool-size'
,好像也没有设置。
最后,它说 Key not found: 'url'
。 application.conf
中有两个 url
键,这意味着代码没有在配置文件的正确部分查找。当您希望它寻找 appone.db-config.url
.
时,它可能正在寻找 appone.url
我有一个 ConfigLoader,我很确定它可以正常工作。我怀疑我没有正确使用 application.conf 文件,或者我的包含 prd.env 和 dev.env 的目录可能不在正确的位置。
我期望发生的事情:
当我输入 sbt run
时,ConfigLoader 读取 application.conf 文件,发现该文件中有变量。然后根据它所处的环境检查 prd.env 或 dev.env,最后加载变量。我想要这个,这样我就可以为 dev 和 prd 使用不同的数据库。
- 我不知道它如何找到包含 prd.env 和 dev.env 的 Meta 目录(见图)。
- 我不知道它如何判断环境是在 dev 还是 prd。
- 现在的目标是部署此应用程序,这就是我需要这些环境变量才能工作的原因。
我真的很感谢所有的帮助,但请尝试详细说明你的答案,因为我真的被困住了,简短的答案通常假设我知道的比我知道的多。谢谢:)
相关技术栈:
- HTTP4S,
- 猫,
- 杜比,
- PostgreSQL
application.conf 文件如下:
appone {
environment = ${ENV}
server-config {
url = ${?BASE_URL}
host = "0.0.0.0"
port = 8080
}
db-config {
driver = "org.postgresql.Driver"
url = ${?DATABASE_URL}
user = ${?APPONE_POSTGRES_USER}
password = ${?PASSWORD}
connection-threads = 4
}
}
Meta/dev.env 文件(我也有一个 Meta/prd.env 但由于内容的原因在这里显示了它)
ENV=dev
BASE_URL=http://localhost:8080/
DATABASE_URL=jdbc:postgresql://localhost:5400/bookswapdb
APPONE_POSTGRES_USER=su
PASSWORD=password
加载配置文件如下:
package com.fullstackryan.appone.config
import cats.ApplicativeError
import cats.implicits._
import pureconfig.error.ConfigReaderException
import pureconfig.{ConfigReader, ConfigSource, Derivation}
import shapeless.the
trait LoadConfig[F[_], TConfig] {
def load: F[TConfig]
}
object LoadConfig {
def load[F[_], TConfig](implicit loadConfig: LoadConfig[F, TConfig]): F[TConfig] =
the[LoadConfig[F, TConfig]].load
def apply[F[_], TConfig](
implicit reader: Derivation[ConfigReader[TConfig]], ae: ApplicativeError[F, Throwable]
): LoadConfig[F, TConfig] =
new LoadConfig[F, TConfig] {
def load: F[TConfig] = ApplicativeError[F, Throwable].fromEither {
ConfigSource.default
.at("appone")
.load[TConfig]
.leftMap(ConfigReaderException(_))
}
}
}
错误
pureconfig.error.ConfigReaderException: Cannot convert configuration to a scala.runtime.Nothing$. Failures are:
at 'appone.db-config':
- (application.conf @ jar:file:/Users/ryanmcavoy/fullStackRyan/appone/target/bg-jobs/sbt_3cc4b1f5/job-11/target/419ddc2c/5befcb57/appone_2.13-0.0.1-SNAPSHOT.jar!/application.conf: 10) Key not found: 'url'.
- (application.conf @ jar:file:/Users/ryanmcavoy/fullStackRyan/appone/target/bg-jobs/sbt_3cc4b1f5/job-11/target/419ddc2c/5befcb57/appone_2.13-0.0.1-SNAPSHOT.jar!/application.conf: 10) Key not found: 'username'.
- (application.conf @ jar:file:/Users/ryanmcavoy/fullStackRyan/appone/target/bg-jobs/sbt_3cc4b1f5/job-11/target/419ddc2c/5befcb57/appone_2.13-0.0.1-SNAPSHOT.jar!/application.conf: 10) Key not found: 'pool-size'.
at com.fullstackryan.appone.config.LoadConfig$$anon.$anonfun$load(LoadConfig.scala:25)
at cats.syntax.EitherOps$.leftMap$extension(either.scala:172)
at com.fullstackryan.appone.config.LoadConfig$$anon.load(LoadConfig.scala:25)
at com.fullstackryan.appone.server.ApponeServer$.$anonfun$stream(ApponeServer.scala:32)
at com.fullstackryan.appone.server.ApponeServer$.$anonfun$stream$adapted(ApponeServer.scala:31)
at fs2.Stream$.$anonfun$flatMap(Stream.scala:1188)
at fs2.internal.FreeC$.go(Algebra.scala:609)
at fs2.internal.FreeC$.$anonfun$flatMapOutput(Algebra.scala:616)
at fs2.internal.FreeC$$anon.cont(Algebra.scala:53)
at fs2.internal.FreeC$ViewL$$anon$$anon.cont(Algebra.scala:242)
at fs2.internal.FreeC$ViewL$.mk(Algebra.scala:231)
at fs2.internal.FreeC$ViewL$.apply(Algebra.scala:220)
at fs2.internal.FreeC.viewL(Algebra.scala:106)
at fs2.internal.FreeC$.go(Algebra.scala:414)
at fs2.internal.FreeC$.$anonfun$compile(Algebra.scala:464)
at fs2.internal.FreeC$.$anonfun$compile(Algebra.scala:430)
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.14")
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10")
addSbtPlugin("au.com.onegeek" % "sbt-dotenv" % "2.1.204")
// deploy heroku
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.6")
addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.0")
当通过 sbt run
运行 时,环境由您 运行 sbt 所在的 shell 设置。定义一个 dev.env
文件本身没有任何作用。
设置sbt所在环境的机制运行会因你的shell而异。
例如,如果 bash 是您的 shell(这在其他与 Bourne 兼容的 shell 中值得尝试),请在环境变量前加上 export
,例如:
export ENV=dev
然后您将从 dev.env
导出的环境变量合并到您的 bash 环境中
source meta/dev.env
然后将设置这些环境变量,从而在您的 shell 会话期间将其合并到您的配置中(即它们将继续跨越多个 sbt run
s 直到您退出 shell).如果您更改 dev.env
,它们将在您再次 source meta/dev.env
之前可用。
看到错误提示 application.conf: Key not found: 'username'
的地方了吗?这意味着它正在那个 application.conf
文件中寻找一些 username
但没有找到它。如果您自己查看 application.conf
文件,您会发现其中确实没有名为 username
的设置。有一个叫做 user
,也许这就是你想要的?
我们也看到 Key not found: 'pool-size'
,好像也没有设置。
最后,它说 Key not found: 'url'
。 application.conf
中有两个 url
键,这意味着代码没有在配置文件的正确部分查找。当您希望它寻找 appone.db-config.url
.
appone.url