Reputation: 1171
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"
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.
Upvotes: 20
Views: 9688
Reputation: 3312
In case you would like to copy an entire folder/directory recursively you can also use the Universal plugin (similar to @2rs2ts answer). It has a helper method that will copy a local folder into the image.
import com.typesafe.sbt.packager.MappingsHelper.directory
Universal / mappings ++= directory("path/to/myFolder")
The "path/to/folder" is relative to your project root directory.
Directory will be copied to /opt/docker/myFolder in the target image
Upvotes: 1
Reputation: 1377
You can add an entire directory to a Docker image's file system by first making it available using dockerPackageMappings
, and then COPYing it as an additional Docker command.
import NativePackagerHelper._
dockerPackageMappings in Docker ++= directory(baseDirectory.value / ".." / "frontend" )
dockerCommands ++= Seq(
Cmd("COPY", "frontend /opt/frontend"),
)
Upvotes: 1
Reputation: 6710
For sbt-docker plugin, not sbt-native-packager
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 {
from(s"$namespace/$baseImageName:$baseImageTag")
...
add(dockerFiles("some-file.ext"), s"$targetPath/some-file.ext")
...
}
}
Upvotes: 5
Reputation: 577
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.
The files located in /src/universal
will be available in the runtime directory for the Scala app in the Docker container. This means that if your app has /src/universal/example.txt
, then it can be accessed with scala.io.Source.fromFile("./example.txt")
Upvotes: 13
Reputation: 360
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@_*) =>
Seq(
from,
Cmd("Add", "ssh_config", "/sbin/.ssh/config")
) ++ rest
})
Upvotes: 4
Reputation: 11066
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...
Upvotes: 24