NativePackegerでzip化するところまでは、各々抜かりなく……。
アプリzipファイルのルートにDockerfileファイルが必要ならしい
Dockefileはパッケージ名のディレクトリと同じレベルに置かなければいけない。
が、パッケージ名のディレクトリの下にファイルを追加する方法は見つかるのだが、その方法がどうも見つからない。
探せていない可能性は高い。
AWS+activator(sbt)でこんなことをやってる人は、それなりにいるはずだから。
でも、まぁ、せっかく書いたんで、ここに記録しておく。
早い話が、sbtのdistタスクの成果物(zipファイル)にDockerfileとか、Dockerrun.aws.jsonとか、.ebextensionsとかを突っ込むタスクを作ればいいんだろ?
ほい。
build.sbt
// ---------------------------------------------------------------------------------------------------------------------
//
// sbt makeEBで、以下のTaskが実行される
//
//
//
// プロジェクトに追加するタスクの定義
//
lazy val makeEB = taskKey[File]("Append AWS Dockerfile")
//
// プロジェクトに追加するタスクの実体
//
// dist.valueは、"dist"Taskの出力(Zipファイル)のFileインスタンス
// だいたい、"target/universe/[package_name].zip"になるはず。
// これを参照することで、distを実行した後、ここを実行するイメージになる
makeEB := appendToRoot(thisProject.value, dist.value)
// ---------------------------------------------------------------------------------------------------------------------
//
// ここ以降が、Taskの本体
//
//
// Task[makeEB]に必要なImport
import java.io.File
import java.net.URI
import java.nio.file.{FileSystems, Files, Paths}
import java.util
//
// ZipファイルのRootにDockerfileファイルを追加する
//
def appendToRoot(project:ResolvedProject, zip_file:File): File = {
val path = zip_file.toPath
val uri = URI.create("jar:" + path.toUri)
// 既存のZipファイルにファイルを追加する
val env = new util.HashMap[String, String]()
env.put("create", "false")
env.put("encoding", "UTF-8")
val zipfs = FileSystems.newFileSystem(uri, env)
// zip_root以下のファイル/ディレクトリをZipファイルのroot以下にコピーする
val root = project.base.toPath.resolve("zip_root")
getFile(root.toFile) match {
case Some(files) =>
files.foreach {
file =>
val zipFilePath = zipfs.getPath(root.relativize(file.toPath).toString)
if (file.isDirectory) {
if (!zipFilePath.toFile.exists()) {
Files.createDirectories(zipFilePath)
}
} else {
Files.copy(file.toPath, zipFilePath)
}
}
zipfs.close()
println("[info] zip_root is appended")
case _ =>
// zip_rootがない、あるいは中身がない場合、なにもしない
}
zip_file
}
/**
* file以下を再帰的に走査し、ディレクトリ優先でリスト化する
*
* @param file 対象File
* @return 以下のファイル要素
*/
def getFile(file: File): Option[Array[File]] = {
if (null == file || !file.exists()) {
None
} else if (file.isFile) {
Option(Array(file))
} else {
val current: Array[File] = file.listFiles()
val children: Array[File] = current.filter(_.isDirectory).flatMap(getFile).flatten
Option(Array.concat(current, children))
}
}
// makeEB.value
[project_root]/zip_root以下のファイルをzipファイルのルート以下に突っ込みます。