title: how to create an All-In-One docker image using sbt-docker and sbt-assembly
body: <p>I am using sbt-assembly to get fat jars and using sbt-docker to create and push docker images. My project is multi-module which has multiple web services, UI, database etc. Since my base docker image is big (800M), I want to create a docker image containing all the fat jars, so that I can easily test in cloud using one modest machine. I call this solution as All-FatJars-in-One (AFIO). I have trouble to build such AFIO docker image thus this post.</p>
  
  <p>Suppose this multi-module project has module root and mod1, below is the build.scala:</p>
  
  <pre><code>val exeProjs = Seq(mod1)
  
  lazy val root = Project("root", file(".")).
    enablePlugins(DockerPlugin).
    aggregate(exeProjs.map(_.project): _*).
    dependsOn(exeProjs.map(_ % "compile-&gt;test"): _*).
    settings(basicSettings: _*).
    settings(
      docker &lt;&lt;= docker dependsOn assembly,
      dockerfile in docker := {
        //get root artifact path like 
        // /home/me/root/target/scala-2.11/root-assembly-0.1-SNAPSHOT.jar 
        val parentArtifact = (assemblyOutputPath in assembly).value
  
        new Dockerfile {
          from("java:8")
          exeProjs.map(proj =&gt; {
            val projName = proj.id
  
            // fullPathToMod1Art will be like
            // /home/me/root/mod1/target/scala-2.11/mod1-assembly-0.1-SNAPSHOT.jar 
            fullPathToMod1Art = { NASTY parsing to get mo1 artifact }               
  
            val artifactTargetPath = s"/app/$projName/$artifact"
            addRaw(fullPathArt, artifactTargetPath)
        })
      }
    }
  
    imageNames in docker := Seq(
      ImageName("myaccount/root:v1")
    )
  )
  
  lazy val mod1 = Project("mod1", file("mod1")).
    enablePlugins(DockerPlugin).
    settings(basicSettings: _*).
    settings(
    libraryDependencies ++= Seq(spray_can, spray_routing, akka_actor, junit),
  
    docker &lt;&lt;= docker dependsOn assembly,
  
    dockerfile in docker := {
      val artifact = (assemblyOutputPath in assembly).value
      val artifactTargetPath = s"/app/${artifact.name}"
      new Dockerfile {
        from("java:8")
        add(artifact, artifactTargetPath)
        entryPoint("java", "-jar", artifactTargetPath)
      }
    },
  
    imageNames in docker := Seq(
      ImageName("myaccount/mod1:v1")
    )
  )
  </code></pre>
  
  <p><strong>Problems:</strong></p>
  
  <ol>
  <li><p>above code does not work because the root module cannot find mod1 artifact even I have verified fullPathToMod1Art is correct for the generated mod1 artifact. I specified root dependsOn mod1 by compile->test since I don't know what other configurations are better to describe the need: root's docker image creation depends on mod1 fat jar generation.</p></li>
  <li><p>As you see, there is nasty path parsing to get mod1 artifact path in root module settings. There must be better way.</p></li>
  </ol>
  
  <p><strong>Questions:</strong></p>
  
  <p>If sbt-docker + sbt-assembly solution supports AFIO model, how to do it correctly so above two problems are solved elegantly? If they do not support, what other plugins can help?</p>
  
  <p>Appreciate for any clue.</p>