ADD/COPY files with sbt-native-packager's docker support

I’m using sbt-native-packager 1.0.0-M5 to create my docker image. I need to add a file that’s not a source file or in the resource folder. My docker commands are as follows:

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")

It fails with: msg="test.txt: no such file or directory"

  • AWS Elastic Beanstalk deploying Docker with simple SpringBoot Eureka image failure
  • collectd data not showing in influxdb container
  • Default Docker entrypoint
  • Port forwarding in when running a Tomcat Docker in an AWS Elastic Beanstalk application
  • Restore Tensorflow model on docker
  • hyperkube proxy, kubelet can't find iptables chain, rkt run --net=host
  • So after digging around a bit it seems I need to have test.txt in target/docker/stage. Then it works. But how do I get it there automatically? The file is actually in the root folder of the project.

  • Chef-Client fails to get the ruby gem during chef provisioning
  • Docker container not starting a second time (iptables)
  • Magento2 Docker Devbox Exception
  • Docker scale and elasticsearch
  • How Docker and Ansible fit together to implement Continuos Delivery/Continuous Deployment
  • Can't connect pgbouncer and postgres running with docker
  • 4 Solutions collect form web for “ADD/COPY files with sbt-native-packager's docker support”

    I managed to get it to work by adding the file to mappings in Universal. So for you, you would need something like this:

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

    You won’t need the COPY command if you do this, by the way.

    Now, I’m not sure if this is going to add this mapping to other sbt-native-packager plugins. I hope a commenter can tell me whether or not this is true, but my intuition is that it will do so, which might be a dealbreaker for you. But any workaround is better than none, right? If you use Build.scala you could maybe use a VM argument to tell sbt whether or not to add this mapping…

    I was able to get this working using dockerPackageMappings:

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

    I was able to add files this way:

    For example, to add a file located in 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 {
        add(dockerFiles("some-file.ext"), s"$targetPath/some-file.ext")

    You may place all additional files (which must be included in container image) into folder src/universal. Content of that folder will be automatically copied in /opt/app folder within your container image. You don’t need any additional configuration. See “Getting started with Universal Packaging” for additional info.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.