【问题标题】:ADD/COPY files with sbt-native-packager's docker support使用 sbt-native-packager 的 docker 支持添加/复制文件
【发布时间】:2015-04-24 21:47:18
【问题描述】:

我正在使用 sbt-native-packager 1.0.0-M5 来创建我的 docker 映像。我需要添加一个不是源文件或资源文件夹中的文件。我的docker命令如下:

dockerCommands := Seq(
  Cmd("FROM", "myrepo/myImage:1.0.0"),
  Cmd("COPY", "test.txt keys/"), // <-- The failing part
  Cmd("WORKDIR", "/opt/docker"),
  Cmd("RUN", "[\"chown\", \"-R\", \"daemon\", \".\"]"),
  Cmd("USER", "daemon"),
  ExecCmd("CMD", "echo", "Hello, World from Docker")
)

它失败了:msg="test.txt: no such file or directory"

所以在挖掘了一下之后,我似乎需要在target/docker/stage 中有test.txt。然后它工作。但是我如何自动获得它呢?该文件实际上在项目的根文件夹中。

【问题讨论】:

  • 我也一直在想这个。我可以告诉你,将其添加为映射(mappings in DockerdockerPackageMappings in Docker)不起作用,尽管它是 seeming that should work

标签: scala sbt docker sbt-native-packager


【解决方案1】:

我设法通过将文件添加到mappings in Universal 来使其工作。所以对你来说,你需要这样的东西:

mappings in Universal += file("test.txt") -> "keys/test.txt"

顺便说一句,如果你这样做,你将不需要COPY 命令。

现在,我不确定这是否会将此映射添加到其他 sbt-native-packager 插件。我希望评论者能告诉我这是否属实,但我的直觉是它会这样做,这对你来说可能会破坏交易。但是任何解决方法都比没有好,对吧?如果你使用Build.scala,你可以使用VM参数告诉sbt是否添加这个映射......

【讨论】:

  • 我可以通过这种方式将文件放在 Docker 工作目录中,但不幸的是在根目录中。即映射到“/test.txt”似乎忽略了前面的斜杠。
  • 您可以运行另一个命令将文件移动到您想要的位置:dockerCommands += ExecCmd("RUN", "mv", s"${(defaultLinuxInstallLocation in Docker).value}/keys/ test.txt", "/wherever/you/want/test.txt")
  • 这些映射的基本目录是什么?比如,相对于项目根目录中的build.sbt,原生打包程序会在哪里寻找test.txt
  • @kag0 我写这个答案已经 3 年了(自从我上次从事 sbt 项目以来已经 2.5 年了),我再也无法访问代码了。所以不幸的是我不记得了。
  • @2rs2ts 我已经通过一些实验弄清楚了。基目录是项目根目录(所以同一目录build.sbt 在)。但请注意,如果您在子项目中,则基本目录仍然是 ROOT 项目build.sbt 的同一目录,而不是子项目build.sbt
【解决方案2】:

您可以将所有附加文件(必须包含在容器映像中)放入文件夹src/universal。该文件夹的内容将自动复制到容器映像内的/opt/app 文件夹中。您不需要任何额外的配置。请参阅"Getting started with Universal Packaging" 了解更多信息。

/src/universal 中的文件将在 Docker 容器中的 Scala 应用程序的运行时目录中可用。这意味着如果你的应用有/src/universal/example.txt,那么可以使用scala.io.Source.fromFile("./example.txt")访问它

【讨论】:

    【解决方案3】:

    我可以使用dockerPackageMappings 来完成这项工作:

    dockerPackageMappings in Docker += (baseDirectory.value / "docker" / "ssh_config") -> "ssh_config"
    
    dockerCommands := (dockerCommands.value match {
      case Seq(from@Cmd("FROM", _), rest@_*) =>
        Seq(
         from,
         Cmd("Add", "ssh_config", "/sbin/.ssh/config")
      ) ++ rest
    })
    

    【讨论】:

      【解决方案4】:

      对于 sbt-docker 插件,而不是 sbt-native-packager

      我可以通过这种方式添加文件:

      例如,添加一个位于src/main/resources/docker/some-file.ext的文件

      dockerfile in docker := {
        val targetPath = "/usr/app"
      
        // map of (relativeName -> File) of all files in resources/docker dir, for convenience
        val dockerFiles = {
          val resources = (unmanagedResources in Runtime).value
          val dockerFilesDir = resources.find(_.getPath.endsWith("/docker")).get
          resources.filter(_.getPath.contains("/docker/")).map(r => dockerFilesDir.toURI.relativize(r.toURI).getPath -> r).toMap
        }
      
        new Dockerfile {
          from(s"$namespace/$baseImageName:$baseImageTag")
          ...
          add(dockerFiles("some-file.ext"), s"$targetPath/some-file.ext")
          ...
        }
      }
      

      【讨论】:

      • 不幸的是,这是 sbt-docker 插件的解决方案,而不是 sbt-native-packager。
      • 嗯,它帮助了我,因为我试图为 sbt-docker 寻找解决方案,而谷歌把我带到了这里。 :)
      【解决方案5】:

      您可以将整个目录添加到 Docker 映像的文件系统,方法是首先使用 dockerPackageMappings 使其可用,然后将其作为附加 Docker 命令复制。

      import NativePackagerHelper._
      dockerPackageMappings in Docker ++= directory(baseDirectory.value / ".." / "frontend" )
      
      dockerCommands ++= Seq(
        Cmd("COPY", "frontend /opt/frontend"),
      )
      

      【讨论】:

        猜你喜欢
        • 2019-10-15
        • 2016-07-27
        • 2015-10-03
        • 2016-08-17
        • 2017-07-10
        • 2020-03-25
        • 2020-11-07
        • 2015-12-22
        • 2017-04-12
        相关资源
        最近更新 更多