Docker

Automatically build docker images from your mill project.

Requires the docker CLI to be installed.

In the simplest configuration just extend DockerModule and declare a DockerConfig object.

build.sc
import mill._, scalalib._

import $ivy.`com.lihaoyi::mill-contrib-docker:$MILL_VERSION`
import contrib.docker.DockerModule

object foo extends JavaModule with DockerModule {
  object docker extends DockerConfig
}

Then

$ mill foo.docker.build
$ docker run foo

Configuration

Configure the image by overriding tasks in the DockerConfig object

object docker extends DockerConfig {
  // Override tags to set the output image name
  def tags = List("aws_account_id.dkr.ecr.region.amazonaws.com/hello-repository")

  def baseImage = "openjdk:11"

  // Configure whether the docker build should check the remote registry for a new version of the base image before building.
  // By default this is true if the base image is using a latest tag
  def pullBaseImage = true
  // Add container metadata via the LABEL instruction
  def labels = Map("version" -> "1.0")
  // TCP ports the container will listen to
  def exposedPorts = Seq(8080, 443)
  // UDP ports the container will listen to
  def exposedUdpPorts = Seq(80)
  // The names of mount points, these will be translated to VOLUME instructions
  def volumes = Seq("/v1", "/v2")
  // Environment variables to be set in the container (ENV instructions)
  def envVars = Map("foo" -> "bar", "foobar" -> "barfoo")
  // JVM runtime options such as heap size settings
  def jvmOptions = Seq("-Xmx1024M", "-XX:+HeapDumpOnOutOfMemoryError")
  // Add RUN instructions
  def run = Seq(
    "/bin/bash -c 'echo Hello World!'",
    "useradd -ms /bin/bash new-user"
  )
  // User to use when running the image
  def user = "new-user"
  // Optionally override the docker executable to use something else
  def executable = "podman"
}

Run mill in interactive mode to see the docker client output, like mill -i foo.docker.build.