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"

  • Using COPY on dockerfile for apache build
  • Strong-PM in Docker Container App Connect to Host MongoD
  • docker port mapping for consul agent
  • Deploy Cloudsuite benchmark using Docker swarm mode
  • Flanneld not working in Kubernetes Multinode Example
  • python3 tkinter ubuntu trusty does not work under virtual environment
  • 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.

  • Run MongoDB in a Docker container with no volumes
  • How to configure the 'smtp ' settings on docker/redmine container instance?
  • Using docker to run a distributed computation
  • Why does Docker have a daemon?
  • Docker LAMP stack - lstat apache_default: no such file or directory?
  • How to run a network-isolated docker container with docker-py?
  • 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.