使用环境变量配置 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 安装的容器中。我们正在使用 SbtReactiveAppPluginbuild.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 加载您的配置