使用环境变量配置 Docker Lagom Scala 应用程序的部署
Using environment variables to configure Docker deployment of Lagom Scala application
我们正在开发几个基于 Lagom 的 Scala 微服务。它们是使用 application.conf 中的变量替换配置的,例如
mysql = {
url = "jdbc:mysql://"${?ENV_MYSQL_DATABASE_URL}
在开发过程中,我们通过调用 System.setProperty("ENV_MYSQL_DATABASE_URL", url)
的 env.sbt
文件将这些变量设置为 Java 系统属性。这工作正常。
现在我想将其部署到本地 Docker 安装的容器中。我们正在使用 SbtReactiveAppPlugin
从 build.sbt
和 运行 sbt Docker/publishLocal
构建 Docker 图像。这按预期工作,创建了一个 Docker 图像,我可以启动它。
但是,使用标准 docker 或 docker-compose 机制传递环境变量似乎不起作用。虽然我可以看到环境变量在 Docker 容器内设置正确(在 bash 上使用 env
以及在服务内执行 log.debug("ENV_MYSQL_DATABASE_URL via env: " + sys.env("ENV_MYSQL_DATABASE_URL"))
进行验证),但它们是application.conf
未使用且在配置系统中不可用。值为empty/unset(通过configuration.getString("ENV_MYSQL_DATABASE_URL").toString()
验证,mysql系统和其他系统抛出的异常)。
我让它工作的唯一方法是通过 JAVA_OPTS=-D ENV_MYSQL_DATABASE_URL=....
将它混入 JAVA_OPTS
。然而,这似乎是一种 hack,并且似乎无法很好地适应数十个环境参数。
我是不是遗漏了什么,有没有办法在 Lagom 应用程序和 application.conf 中轻松使用环境变量?
谢谢!
多年来,我一直在 docker 容器中使用 Lightbend config 通过环境变量配置 Lagom 服务,所以我知道这是可以做到的,而且根据我的经验,它非常简单。
考虑到这一点,当您说 application.conf
未使用它们时,您的意思是它们未设置吗?请注意,除非您将非常具体的选项作为 Java 属性 传递,否则 configuration.getString("ENV_MYSQL_DATABASE_URL")
不会从环境变量中读取,因此检查不会告诉您有关 mysql.url
受环境变量影响。 configuration.getString("mysql.url")
会让您更好地了解正在发生的事情。
我怀疑实际上您的 Docker 图像是使用硬编码的开发模式属性构建的,并且由于 Java 系统属性优先于其他所有属性,它们正在影响环境变量。
您可能会发现按照以下几行构建您的 application.conf
很有用:
mysql_database_url = "..." # Some reasonable default default for dev-mode
mysql_database_url = ${?ENV_MYSQL_DATABASE_URL}
mysql {
url = "jdbc://"${mysql_database_url}
}
在这种情况下,您对开发人员有一个合理的默认设置(可能以与该配置兼容的方式在文档中包含一些针对 运行 MySQL 的说明)。然后可以通过设置 Java 属性(例如 JAVA_OPTS=-Dmysql_database_url
)或设置 ENV_MYSQL_DATABASE_URL
环境变量来覆盖默认值。
虽然我同意 Levi Ramsey 提供的答案,但我建议您使用 typesafe's config 加载您的配置
我们正在开发几个基于 Lagom 的 Scala 微服务。它们是使用 application.conf 中的变量替换配置的,例如
mysql = {
url = "jdbc:mysql://"${?ENV_MYSQL_DATABASE_URL}
在开发过程中,我们通过调用 System.setProperty("ENV_MYSQL_DATABASE_URL", url)
的 env.sbt
文件将这些变量设置为 Java 系统属性。这工作正常。
现在我想将其部署到本地 Docker 安装的容器中。我们正在使用 SbtReactiveAppPlugin
从 build.sbt
和 运行 sbt Docker/publishLocal
构建 Docker 图像。这按预期工作,创建了一个 Docker 图像,我可以启动它。
但是,使用标准 docker 或 docker-compose 机制传递环境变量似乎不起作用。虽然我可以看到环境变量在 Docker 容器内设置正确(在 bash 上使用 env
以及在服务内执行 log.debug("ENV_MYSQL_DATABASE_URL via env: " + sys.env("ENV_MYSQL_DATABASE_URL"))
进行验证),但它们是application.conf
未使用且在配置系统中不可用。值为empty/unset(通过configuration.getString("ENV_MYSQL_DATABASE_URL").toString()
验证,mysql系统和其他系统抛出的异常)。
我让它工作的唯一方法是通过 JAVA_OPTS=-D ENV_MYSQL_DATABASE_URL=....
将它混入 JAVA_OPTS
。然而,这似乎是一种 hack,并且似乎无法很好地适应数十个环境参数。
我是不是遗漏了什么,有没有办法在 Lagom 应用程序和 application.conf 中轻松使用环境变量?
谢谢!
多年来,我一直在 docker 容器中使用 Lightbend config 通过环境变量配置 Lagom 服务,所以我知道这是可以做到的,而且根据我的经验,它非常简单。
考虑到这一点,当您说 application.conf
未使用它们时,您的意思是它们未设置吗?请注意,除非您将非常具体的选项作为 Java 属性 传递,否则 configuration.getString("ENV_MYSQL_DATABASE_URL")
不会从环境变量中读取,因此检查不会告诉您有关 mysql.url
受环境变量影响。 configuration.getString("mysql.url")
会让您更好地了解正在发生的事情。
我怀疑实际上您的 Docker 图像是使用硬编码的开发模式属性构建的,并且由于 Java 系统属性优先于其他所有属性,它们正在影响环境变量。
您可能会发现按照以下几行构建您的 application.conf
很有用:
mysql_database_url = "..." # Some reasonable default default for dev-mode
mysql_database_url = ${?ENV_MYSQL_DATABASE_URL}
mysql {
url = "jdbc://"${mysql_database_url}
}
在这种情况下,您对开发人员有一个合理的默认设置(可能以与该配置兼容的方式在文档中包含一些针对 运行 MySQL 的说明)。然后可以通过设置 Java 属性(例如 JAVA_OPTS=-Dmysql_database_url
)或设置 ENV_MYSQL_DATABASE_URL
环境变量来覆盖默认值。
虽然我同意 Levi Ramsey 提供的答案,但我建议您使用 typesafe's config 加载您的配置