sbt-docker is a sbt plugin which builds Docker images for your projects.
- sbt
- Docker
Add sbt-docker as a dependency in project/plugins.sbt
:
addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.1.0")
sbt-docker is an auto plugin, this means that sbt version 0.13.5 or higher is required.
Start by enabling the plugin in your build.sbt
file:
enablePlugins(DockerPlugin)
This sets up some settings with default values and adds tasks such as docker
which builds a Docker image.
The only required setting that is left to define is dockerfile in docker
.
If you want your Dockerfile to contain one or several artifacts (such as JAR files) that your
project generates, then you must make the docker
task depend on the tasks that generate them.
It could for example be with the package
task or with tasks from plugins such as
sbt-assembly.
Here is how to make the docker task depend on the sbt package
task:
docker <<= docker.dependsOn(`package`.in(Compile, packageBin))
In order to produce a Docker image a Dockerfile must be defined.
It should be defined at the dockerfile in docker
key.
There is a mutable and an immutable Dockerfile class available, both provides a DSL which resembles
the plain text Dockerfile format.
The mutable class is default and is used in the following examples.
Example with the sbt package
task.
docker <<= docker.dependsOn(`package`.in(Compile, packageBin))
dockerfile in docker := {
val jarFile = artifactPath.in(Compile, packageBin).value
val classpath = (managedClasspath in Compile).value
val mainclass = mainClass.in(Compile, packageBin).value.getOrElse(sys.error("Expected exactly one main class"))
val jarTarget = s"/app/${jarFile.getName}"
// Make a colon separated classpath with the JAR file
val classpathString = classpath.files.map("/app/" + _.getName)
.mkString(":") + ":" + jarTarget
new Dockerfile {
// Base image
from("dockerfile/java")
// Add all files on the classpath
add(classpath.files, "/app/")
// Add the JAR file
add(jarFile, jarTarget)
// On launch run Java with the classpath and the main class
entryPoint("java", "-cp", classpathString, mainclass)
}
}
Example with the sbt-assembly plugin:
// Make the docker task depend on the assembly task, which generates a fat JAR file
docker <<= (docker dependsOn assembly)
dockerfile in docker := {
val artifact = (outputPath in assembly).value
val artifactTargetPath = s"/app/${artifact.name}"
new Dockerfile {
from("dockerfile/java")
add(artifact, artifactTargetPath)
entryPoint("java", "-jar", artifactTargetPath)
}
}
Have a look at DockerfileExamples for different ways of defining a Dockerfile.
To build an image use the docker
task.
Simply run sbt docker
from your prompt or docker
in the sbt console.
An image that have already been built can be pushed with the dockerPush
task.
To both build and push an image use the dockerBuildAndPush
task.
The imageNames in docker
key is used to determine which image names to push.
Set imageNames in docker
of type Seq[sbtdocker.ImageName]
.
Example:
imageNames in docker := Seq(
ImageName("organization/name:tag"),
ImageName(
namespace = Some(organization.value),
repository = name.value,
tag = Some("v" + version.value)
)
)
Use the key buildOptions in docker
to set build options.
Example:
buildOptions in docker := BuildOptions(
cache = false,
removeIntermediateContainers = BuildOptions.Remove.Always,
pullBaseImage = BuildOptions.Pull.Always)
If you have a standalone JVM application that you want a simple Docker image for.
Then you can use dockerAutoPackageJavaApplication(fromImage, exposedPorts, exposedVolumes, username)
which will setup some settings for you, including a Dockerfile.
Its very basic, so if you have more advanced needs then define your own Dockerfile.
See example projects.