1

我正在使用 sbt-native-packager 和 sbt-docker 来生成 Docker 映像,如本教程中所述。Docker 映像不会运行(权限被拒绝),并且在检查时发现它bin/start被创建为一个空目录。

dan@cobalt:~/projects/confabulous/deva$ ls -l target/universal/stage/bin/
total 24
-rwxrw-r-- 1 dan dan 11591 Aug  5 20:44 deva
-rw-rw-r-- 1 dan dan  6211 Aug  5 20:44 deva.bat
drwxrwxr-x 2 dan dan  4096 Dec 31  1969 start

由于某种原因,它也有一个空时间戳。为什么它被创建为目录而不是 shell 脚本?

这是我的 plugins.sbt:

addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.4")

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.4")

addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.1")

addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "0.5.0")

resolvers += Classpaths.sbtPluginReleases

这是我的 build.sbt:

import DockerKeys._
import sbtdocker.{Dockerfile, ImageName}
import com.typesafe.sbt.packager.Keys._

organization  := "com.confabulous"

name          := "deva"

version       := "0.0.1"

scalaVersion  := "2.10.3"

scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8", "-language:postfixOps")

resolvers ++= Seq(
  "sonatype releases"  at "https://oss.sonatype.org/content/repositories/releases/",
  "sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/",
  "typesafe repo"      at "http://repo.typesafe.com/typesafe/releases/"
)

libraryDependencies ++= Seq(
  "ch.qos.logback"      %   "logback-classic" % "1.0.9",
  "com.typesafe.akka"   %   "akka-slf4j_2.10" % "2.3.3",
  "com.typesafe.akka"   %%  "akka-actor"      % "2.3.3",
  "com.typesafe.akka"   %%  "akka-remote"     % "2.3.3",
  "com.typesafe.akka"   %%  "akka-agent"      % "2.3.3",
  "com.typesafe.slick"  %%  "slick"           % "2.0.1-RC1",
  "org.mozilla"         %   "rhino"           % "1.7R4",
  "org.postgresql"      %   "postgresql"      % "9.3-1101-jdbc3",
  "org.msgpack"         %%  "msgpack-scala"   % "0.6.8",
  "com.livestream"      %%  "scredis"         % "1.1.2",
  "com.confabulous"     %%  "messages"        % "0.0.1-SNAPSHOT",
  "com.confabulous"     %%  "db"              % "0.0.1-SNAPSHOT"
)

packageArchetype.java_server

sbtdocker.Plugin.dockerSettings

mappings in Universal += baseDirectory.value / "docker" / "start" -> "bin/start"

docker <<= docker.dependsOn(com.typesafe.sbt.packager.universal.Keys.stage.in(Compile))

// Define a Dockerfile
dockerfile in docker <<= (name, stagingDirectory in Universal) map {
    case (appName, stageDir) =>
        val workingDir = s"/opt/${appName}"
        new Dockerfile {
            // Use a base image that contain Java
            from("relateiq/oracle-java7")
            maintainer("Dan Ellis <dan@halftreelabs.com>")
            expose(1600)
            add(stageDir, workingDir)
            run("chmod",  "+x",  s"/opt/${appName}/bin/${appName}")
            run("chmod",  "+x",  s"/opt/${appName}/bin/start")
            workDir(workingDir)
            entryPointShell(s"bin/start", appName, "$@")
        }
}

imageName in docker := {
    ImageName(
        namespace = Some("confabulous.com"),
        repository = name.value
        //,tag = Some("v" + version.value))
    )
}
4

2 回答 2

3

引用的文章是系列文章的第 2 部分,其中容器的地址通过脚本传递到 Java 程序中。脚本本身在第 1 部分中被引用。

mappings in Universal接受一个(File, String)元组序列。文件被复制到结果图像中字符串指定的路径。

在这种情况下,如果在 处不存在文件baseDirectory.value / "docker" / "start",则无法复制任何内容,结果就是您描述的行为。

您应该创建一个适当的启动脚本,如第 1 部分所述。

于 2014-08-06T15:55:31.343 回答
3

另一种选择是利用sbt-native-packager中对 Docker 的实验性支持。

如果您从 build.sbt 中删除与 Docker 相关的行,并添加一个maintainer设置,您可以:

sbt docker:stage生成一个 Dockerfile 和上下文target/docker/stage

sbt docker:publishLocal生成本地图像

sbt docker:publish生成图像并远程推送

如果要修改传递给启动脚本的命令,可以进行如下修改:

bashScriptExtraDefines := Seq(
  "CLUSTER_IP=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')",
  "addResidual ${CLUSTER_IP}"
)

addResidual是 sbt-native-packager 生成的启动脚本中的一个函数,它为程序的命令行参数添加了一个额外的参数。

addJava是一个向运行程序的 Java 二进制文件添加额外参数的函数。


build.sbt可能看起来像这样:

import com.typesafe.sbt.packager.Keys._

organization  := "com.confabulous"

name          := "deva"

version       := "0.0.1"

scalaVersion  := "2.10.3"

scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8", "-language:postfixOps")

resolvers ++= Seq(
  "sonatype releases"  at "https://oss.sonatype.org/content/repositories/releases/",
  "sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/",
  "typesafe repo"      at "http://repo.typesafe.com/typesafe/releases/"
)

libraryDependencies ++= Seq(
  "ch.qos.logback"      %   "logback-classic" % "1.0.9",
  "com.typesafe.akka"   %   "akka-slf4j_2.10" % "2.3.3",
  "com.typesafe.akka"   %%  "akka-actor"      % "2.3.3",
  "com.typesafe.akka"   %%  "akka-remote"     % "2.3.3",
  "com.typesafe.akka"   %%  "akka-agent"      % "2.3.3",
  "com.typesafe.slick"  %%  "slick"           % "2.0.1-RC1",
  "org.mozilla"         %   "rhino"           % "1.7R4",
  "org.postgresql"      %   "postgresql"      % "9.3-1101-jdbc3",
  "org.msgpack"         %%  "msgpack-scala"   % "0.6.8",
  "com.livestream"      %%  "scredis"         % "1.1.2",
  "com.confabulous"     %%  "messages"        % "0.0.1-SNAPSHOT",
  "com.confabulous"     %%  "db"              % "0.0.1-SNAPSHOT"
)

packageArchetype.java_server

maintainer := "Dan Ellis <dan@halftreelabs.com>"

更多信息应该可以从 sbt-native-packager 文档中获得。也欢迎评论。

于 2014-08-06T16:21:38.987 回答