【问题标题】:Play Framework - Passing Application Arguments via Docker ContainerPlay Framework - 通过 Docker 容器传递应用程序参数
【发布时间】:2017-12-08 14:02:10
【问题描述】:

在 dockerizing 我的 play web 应用程序之前,我能够在运行时执行以下操作:

Joes-Macbook:project-1 joe$ sbt -Dconfig.env=dev run

我可以在 config.env 参数中使用以下 dev、qa、prod 之一,我的应用程序将相应地使用相应的 application.dev.conf 或 application.qa.conf 运行。

现在我的应用程序是一个 docker 容器,这意味着我需要一种方法来注入我的配置文件。我该怎么办?

我想的一种方法是拥有一个 shell 脚本并将其用作入口点。但不确定这可能如何工作?有什么建议吗?

所以当我这样做时

sbt docker:publishLocal

我得到以下 Dockerfile 生成

FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER Joesan <myemail@email.com>
WORKDIR /opt/docker
ADD opt /opt
RUN ["chown", "-R", "daemon:daemon", "."]
USER daemon
ENTRYPOINT ["sh", "-c", "bin/project-1", "-Denv=$configEnv"]
CMD []
ENV configEnv default

我无法在我的 Scala 应用程序中解析 $configEnv。这就是我运行生成的 docker 映像的方式:

docker run -e "configEnv=crap" --rm --name play-8080 -p 8080:9000 joesan/project-1:1.0-SNAPSHOT

【问题讨论】:

    标签: docker playframework sbt


    【解决方案1】:

    您可以在environment variable when you use docker run(或docker compose)中设置

    docker run -e "deep=purple" ...
    

    这意味着您的 Dockerfile 可以声明 same variable as ENV,并由您的默认 CMD 使用。

    ENV configEnv
    CMD sbt -Dconfig.env=${configEnv} run
    

    虽然,OP 正在使用sbt-native-packagergenerates a Dockerfile
    Issue 861 显示如何将命令添加到生成的 Dockefile:

    dockerCommands ++= Seq (
          // setting the run script executable
          ExecCmd("RUN", "chmod", "u+x", s"${(defaultLinuxInstallLocation in Docker).value}/bin/${executableScriptName.value}")
        )
    

    这意味着你可以这样声明 ENV。

    issue 927 展示了如何覆盖默认的ENTRYPOINT

    dockerEntrypoint := Seq("bin/my-app", "-Dconfig.resource=application-prod.conf")
    

    将两者结合起来应该可以实现我上面提出的解决方案。


    实际上,after discussion,重写是不好的,因为生成的Dcokerfile 会在ENV 声明之后有ENTRYPOINT ,这不好。

    只有添加ENVENTRYPOINT,才能生成正确的Dockerfile,如下图OP sparkr所示。

    【讨论】:

    • 这可能可行,但我使用的是 sbt 本机打包程序,这意味着我无法控制正在生成的 docker 文件,因为在构建项目时会生成 Dockerfile!
    • @sparkr 您可以根据生成的图像轻松制作自己的图像,不是吗?
    • 我想避免这种情况!我刚刚发现有一个可以配置的 dockerEntryPoint:scala-sbt.org/sbt-native-packager/formats/…
    • 有了这个 dockerEntryPoint,我可以编写一个自定义脚本,然后可以接受这个参数!
    • 是的,我看过了,似乎是要走的路!
    【解决方案2】:

    因此,在 VonC 的帮助下,对我的 build.sbt 进行了一些更改,我让它工作了:

    这就是我的 build.sbt 中的内容:

    dockerCommands ++= Seq(
      Cmd("ENV", "configEnv", "default"), // This will be overridden when running!
      // This is the entrypoint where we can run the application against different environments
      ExecCmd("ENTRYPOINT", "sh", "-c", "bin/" + s"${executableScriptName.value}" + " -Denv=$configEnv")
    )
    

    所以当我运行 docker 命令时:

    docker run -e "configEnv=test" --rm --name play-8080 -p 8080:9000 joesan/project-1:1.0-SNAPSHOT
    

    适当的 application.test.conf 被拾取,加载,我的 play 应用程序运行它!

    【讨论】:

    • 干得好! +1。生成 ENTRYPOINT(而不是仅仅覆盖它)是关键。
    • 你的线索确实帮助我解决了这个问题!
    • 我已经编辑了我的答案,指出在这种情况下覆盖 ENTRYPOINT 不是一个好的选择。
    猜你喜欢
    • 2021-09-08
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多