【问题标题】:Using environment variables to configure Docker deployment of Lagom Scala application使用环境变量配置 Lagom Scala 应用的 Docker 部署
【发布时间】:2020-05-09 16:13:46
【问题描述】:

我们正在开发几个基于 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 构建Docker 映像并简单地运行sbt Docker/publishLocal。这按预期工作,创建了一个 Docker 映像,我可以启动它。

但是,使用标准 docker 或 docker-compose 机制传入环境变量似乎不起作用。虽然我可以看到在 Docker 容器内正确设置了环境变量(在 bash 上使用 env 进行验证,也通过在服务内执行 log.debug("ENV_MYSQL_DATABASE_URL via env: " + sys.env("ENV_MYSQL_DATABASE_URL")) 进行验证),但 application.conf 不使用它们并且在配置系统。值为空/未设置(通过configuration.getString("ENV_MYSQL_DATABASE_URL").toString()验证以及mysql系统和其他系统抛出的异常)。

我让它工作的唯一方法是通过JAVA_OPTS=-D ENV_MYSQL_DATABASE_URL=.... 将其添加到JAVA_OPTS 中。但是,这似乎是一种 hack,并且对于几十个环境参数似乎不能很好地扩展。

我是否遗漏了什么,有没有办法轻松使用 Lagom 应用程序和 application.conf 中的环境变量?

谢谢!

【问题讨论】:

    标签: scala docker lagom


    【解决方案1】:

    多年来,我一直使用 Lightbend config 通过 docker 容器中的环境变量来配置 Lagom 服务,所以我知道这是可以做到的,而且根据我的经验,它非常简单。

    考虑到这一点,当您说application.conf 未使用它们时,您的意思是它们未设置吗?请注意,除非您将非常具体的选项作为 Java 属性传递,否则 configuration.getString("ENV_MYSQL_DATABASE_URL") 不会从环境变量中读取,因此检查它不会告诉您有关 mysql.url 是否受环境变量影响的任何信息。 configuration.getString("mysql.url") 会让您更好地了解正在发生的事情。

    我怀疑实际上您的 Docker 映像是使用硬编码的 dev-mode 属性构建的,并且由于 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 环境变量来覆盖默认值。

    【讨论】:

    • 感谢您的精彩回答!这无疑对我帮助很大。关于configuration.getString 不返回环境变量的观点是正确的,这就是误导我的原因。此外,事实证明,配置似乎在很大程度上发挥了作用,但还有一些其他因素在起作用,使情况变得更糟。一个是运行 sbt runAll 并不会真正验证 JWT 令牌,而在 Docker 中运行会,所以它看起来像是在 runAll 中工作,而实际上它甚至没有尝试过。
    【解决方案2】:

    虽然我同意 Levi Ramsey 提供的答案,但我建议您使用 typesafe's config 加载您的配置

    【讨论】:

    • 他正在使用 Lightbend/Typesafe 配置,包含在 Lagom 中。
    猜你喜欢
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 2020-04-15
    • 2018-09-25
    • 1970-01-01
    • 2018-05-21
    相关资源
    最近更新 更多