sbt native packager dockerCommands copy

时间:2018-05-09 12:50:43

标签: docker sbt sbt-native-packager

在互联网上搜索,但在这里找不到解决问题的答案。

我的问题是我想创建一个docker镜像,其中一些自定义sql脚本从本地文件系统复制到docker镜像。

目录结构(多个模块项目)

my_sbt
    + my_app
        - build.sbt ...
    + database
        - build.sbt 
        + scripts
            - ... several sql scripts ...

database / build.sbt包含dockerCommands

dockerCommands := Seq(
  Cmd("FROM", "postgres:9.5"),
  Cmd("EXPOSE", "5432"),
  Cmd("COPY", (baseDirectory.value / "database" / "scripts" / "a.sql").toPath.toAbsolutePath.toString, "/docker-entrypoint-initdb.d/a.sql")
)

如果没有COPY Cmd(即docker run -d --rm -p 5432:5432 <docker image>启动容器,并且docker exec -it <container id> bash可以攻击容器并且在容器bash中由ps -ef验证处理正在运行),则可以成功创建映像。但是,向dockerCommands添加COPY语句会使构建过程sbt docker:publishLocal崩溃,错误为 java.lang.RuntimeException:非零退出值:1

java.lang.RuntimeException: Nonzero exit value: 1
    at com.typesafe.sbt.packager.docker.DockerPlugin$.publishLocalDocker(DockerPlugin.scala:335)
    at com.typesafe.sbt.packager.docker.DockerPlugin$$anonfun$projectSettings$22.apply(DockerPlugin.scala:119)
    at com.typesafe.sbt.packager.docker.DockerPlugin$$anonfun$projectSettings$22.apply(DockerPlugin.scala:117)
...

使用 -d sbt -d docker:publishLocal运行sbt无效,因为它仍然会抛出非零退出值:1 ,这根本没有帮助。

引用本地脚本并将其复制到docker镜像的正确方法是什么?

由于

编辑:

  • 请注意,sbt native packager似乎剥离了前导根路径,即'/'。这样做的原因是什么?以及如何防止领先/剥离?

    [info] Step 3/3 : COPY /path/to/database/scripts/users.sql /docker-entrypoint-initdb.d/users.sql
    [error] lstat path/to/database/scripts/users.sql: no such file or directory
    

1 个答案:

答案 0 :(得分:0)

https://serverfault.com/questions/666149/docker-copy-issue-no-such-file-or-directory/666154#666154处的链接解决了我的问题。

基本上问题来自于docker将本地文件与docker容器相关联的间接方式。

  1. sbt native packager根据Universal 部分中的映射将本地文件复制到target / docker / stage。例如,下面的代码片段将a.sql复制到项目目录下的target / docker / stage / opt / docker / scripts

    mappings in Universal := {
      (mappings in Universal).value :+
      (file(s"${baseDirectory.value}/scripts/a.sql") -> "scripts/a.sql") 
    }
    
  2. sbt native packager然后根据 dockerCommands &#39; s Cmd("COPY", "/opt/docker/scripts/a.sql", "/docker-entrypoint-initdb.d")

    所以The <src> path must be inside the context of the build; ...上下文实际上是从 target / docker / stage / 开始的。