如何使用 Docker 在 Jelastic 上部署 Play 2.5 应用程序?

How to deploy a Play 2.5 app on Jelastic with Docker?

我想在 Jelastic 平台上部署一个使用 Play Framework 2.5 编写的应用程序。我设法将 Play2War 插件用于 Play,但它尚不支持 Play 2.5。

平台的支持推荐使用Docker容器或者VPS。我以前从未与 Docker 合作过。 SBT native packager plugin 提供了一种使用 SBT 自动创建 Docker 文件的方法。 所以这是我的新 plugins.sbt 文件:

// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.11")

// Web plugins
addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.3")
addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.7")
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0")
addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.2")

// Play enhancer - this automatically generates getters/setters for public fields
// and rewrites accessors of these fields to use the getters/setters. Remove this
// plugin if you prefer not to have this feature, or disable on a per project
// basis using disablePlugins(PlayEnhancer) in your build.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0")

// Play Ebean support, to enable, uncomment this line, and enable in your build.sbt using
// enablePlugins(PlayEbean).
addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.0")

// Play Eclipse plugin
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")

// Play native packager support for Docker
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.2.0-M8")

这是我的 build.sbt 文件,其中 Docker 设置基于一些示例:

import com.typesafe.sbt.packager.docker._

name := """VestaWeb"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean, DockerPlugin)

scalaVersion := "2.11.7"

// Configure Docker settings
maintainer in Docker := "eeproperty"

dockerRepository := Some("eeproperty")
dockerBaseImage := "frolvlad/alpine-oraclejdk8:latest"
dockerCommands := dockerCommands.value.flatMap {
  case cmd@Cmd("FROM", _) => List(cmd, Cmd("RUN", "apk update && apk add bash"))
  case other => List(other)
}

// Add dependencies from Maven
libraryDependencies ++= Seq(
  filters,
  javaCore,
  javaJdbc,
  cache,
  javaWs,
  "mysql" % "mysql-connector-java" % "5.1.28",
  "com.stripe" % "stripe-java" % "2.10.0",
  "com.typesafe.play" %% "play-mailer" % "5.0.0",
  "it.innove" % "play2-pdf" % "1.5.1",
  "com.google.api-client" % "google-api-client" % "1.22.0",
  "org.apache.commons" % "commons-compress" % "1.12"
)

// Remove the documentation from the dist
sources in (Compile, doc) := Seq.empty
publishArtifact in (Compile, packageDoc) := false

// Disable strange behavior in local run
fork in run := false

命令:

activator docker:stage

生成此 Docker 文件:

FROM frolvlad/alpine-oraclejdk8:latest
RUN apk update && apk add bash
MAINTAINER eeproperty
WORKDIR /opt/docker
ADD opt /opt
RUN ["chown", "-R", "daemon:daemon", "."]
USER daemon
ENTRYPOINT ["bin/vestaweb"]
CMD []

和其他一些东西,例如 docker/ 文件夹。

命令:

activator docker:publish

将 Docker 文件(可能还有其他文件???)发布到我的 Docker 存储库。我不知道 Docker 向它推送了什么以及它如何知道如何将 Play 应用程序嵌入到 Alpine Linux 基本图像中。

我将我的存储库添加到 Docker 实例和 Jelastic,然后我启动了它。我可以通过 SSH 登录到我的根帐户,但容器中没有与我的应用程序相关的内容。当我尝试在浏览器中打开 Jelastic 节点时没有任何显示。

Play Framework 默认使用端口 9000 和 Jelastic 从端口 80 加载。我想我必须向我的 Docker 文件添加 iptables 命令以将流量从 80 重定向到 9000。

我已经阅读了很多关于 "Dockerize a Play app" 的教程,但他们从未解释如何部署应用程序,只解释了如何使用 activator docker:publishLocal 在本地 运行 容器。

我错过了什么?

我们已经重现了 docker 的问题。 docker 在本地主机上运行良好,但在 Jelastic 环境中运行不佳。 根本原因是 JE-29972-nologin:此帐户不可用)当 docker /sbin/nologin shell 而不是 /bin/bash.

作为解决方法,我们建议您更改 /etc/passwd 并替换 daemon:x:2:2:daemon:/sbin: /sbin/nologindaemon:x:2:2:daemon:/opt/docker:/bin/bash 并在更改后重新启动您的环境。

build.sbt 文件具有 Docker 设置,其中包含提到的解决方法:

import com.typesafe.sbt.packager.docker._

name := """test"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayJava, DockerPlugin)

scalaVersion := "2.11.7"

// Configure Docker settings
maintainer in Docker := "eeproperty"

dockerExposedPorts := Seq(9000)
dockerRepository := Some("eeproperty")
dockerBaseImage := "frolvlad/alpine-oraclejdk8:latest"
dockerCommands := dockerCommands.value.flatMap {
  case cmd@Cmd("FROM", _) => List(cmd, Cmd("RUN", "apk update && apk --no-cache add bash shadow && usermod -s /bin/bash daemon && usermod -d /opt/docker/ daemon"))
  case other => List(other)
}

libraryDependencies ++= Seq(
  javaJdbc,
  cache,
  javaWs
)

sources in (Compile, doc) := Seq.empty
publishArtifact in (Compile, packageDoc) := false