文档

§部署您的应用程序

我们已经了解了如何在开发模式下运行 Play 应用程序,但是 run 命令不应用于在生产模式下运行应用程序。当使用 run 时,Play 会在每次请求时检查 sbt 以查看是否有任何文件发生更改,这可能会对应用程序的性能产生重大影响。

有多种方法可以在生产模式下部署 Play 应用程序。让我们从推荐的方式开始,创建分发工件。

§应用程序密钥

在生产模式下运行应用程序之前,您需要生成应用程序密钥。要详细了解如何执行此操作,请参阅 配置应用程序密钥。在下面的示例中,您将看到使用 -Dplay.http.secret.key=ad31779d4ee49d5ad5162bf1429c32e2e9933f3b。您必须生成自己的密钥才能在部署到生产环境时使用。

§使用 JPA 部署 Play

如果您使用的是 JPA,则需要查看 使用 JPA 部署 Play

§使用 dist 任务

dist 任务构建应用程序的二进制版本,您可以将其部署到服务器,而无需依赖 sbt,服务器只需要 Java 安装。

在 Play 控制台中,只需键入 dist

[my-first-app] $ dist

您将看到类似以下内容

$ sbt
[info] Loading global plugins from /Users/play-developer/.sbt/1.0/plugins
[info] Loading project definition from /Users/play-developer/my-first-app/project
[info] Set current project to my-first-app (in build file:/Users/play-developer/my-first-app/)
[my-first-app] $ dist
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Wrote /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT.pom
[info] Main Scala API documentation to /Users/play-developer/my-first-app/target/scala-2.13/api...
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-web-assets.jar ...
[info] Done packaging.
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT.jar ...
[info] Done packaging.
model contains 21 documentable templates
[info] Main Scala API documentation successful.
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-sans-externalized.jar ...
[info] Done packaging.
[info]
[info] Your package is ready in /Users/play-developer/my-first-app/target/universal/my-first-app-1.0-SNAPSHOT.zip
[info]
[success] Total time: 5 s, completed Feb 6, 2017 2:08:44 PM
[my-first-app] $

这将在应用程序的 target/universal 文件夹中生成一个包含运行应用程序所需所有 JAR 文件的 ZIP 文件。

要运行应用程序,请在目标服务器上解压缩文件,然后运行 bin 目录中的脚本。脚本的名称是您的应用程序名称,它有两个版本,一个 bash shell 脚本和一个 Windows .bat 脚本。

$ unzip my-first-app-1.0.zip
$ my-first-app-1.0/bin/my-first-app -Dplay.http.secret.key=ad31779d4ee49d5ad5162bf1429c32e2e9933f3b

您也可以从命令行指定生产环境的不同配置文件

$ my-first-app-1.0/bin/my-first-app -Dconfig.file=/full/path/to/conf/application-prod.conf

有关使用情况的完整说明,请使用 -h 选项调用启动脚本。

对于 Unix 用户,zip 文件不会保留 Unix 文件权限,因此在扩展文件时,需要将启动脚本设置为可执行文件

$ chmod +x /path/to/bin/<project-name>

或者,可以生成 tar.gz 文件。tar 文件保留权限。调用 Universal / packageZipTarball 任务而不是 dist 任务

sbt Universal / packageZipTarball

默认情况下,dist 任务将包含生成的包中的 API 文档。如果不需要,请在 build.sbt 中添加以下几行

Compile / doc / sources := Seq.empty

Compile / packageDoc / publishArtifact := false

对于包含子项目的构建,上述语句必须应用于所有子项目定义。

§原生打包器

Play 使用 sbt 原生打包器插件。原生打包器插件声明了 dist 任务来创建 zip 文件。调用 dist 任务等同于调用以下命令

[my-first-app] $ Universal / packageBin

可以生成许多其他类型的存档,包括

有关更多信息,请参阅 原生打包器插件文档

§构建服务器发行版

sbt-native-packager 插件提供了一些原型。Play 默认使用的原型称为 Java 服务器原型,它支持以下功能

更多信息可以在 Java 服务器应用程序原型文档 中找到。

§最小 Debian 设置

将以下设置添加到您的构建中

lazy val root = (project in file("."))
  .enablePlugins(PlayScala, DebianPlugin)

Linux / maintainer := "First Lastname <[email protected]>"

Linux / packageSummary := "My custom package summary"

packageDescription := "My longer package description"

然后使用以下命令构建您的包

[my-first-app] $ Debian / packageBin

§最小 RPM 设置

将以下设置添加到您的构建中

lazy val root = (project in file("."))
  .enablePlugins(PlayScala, RpmPlugin)

Linux / maintainer := "First Lastname <[email protected]>"

Linux / packageSummary := "My custom package summary"

packageDescription := "My longer package description"

rpmRelease := "1"

rpmVendor := "example.com"

rpmUrl := Some("http://github.com/example/server")

rpmLicense := Some("Apache v2")

然后使用以下命令构建您的包

[my-first-app] $ Rpm / packageBin

会有一些错误日志。这是因为 rpm 将日志记录到 stderr 而不是 stdout。

§在您的发行版中包含其他文件

项目 dist 目录中包含的任何内容都将包含在原生打包器构建的发行版中。请注意,在 Play 中,dist 目录等同于原生打包器自身文档中提到的 src/universal 目录。

§Play PID 配置

Play 管理自己的 PID,这在 生产配置 中有描述。

由于 Play 使用单独的 pid 文件,我们必须为它提供一个正确的路径,这里就是 packageName.value。pid 文件的名称必须为 play.pid。为了告诉启动脚本将 PID 文件放置在何处,请在 dist/conf 文件夹中放置一个名为 application.ini 的文件,并添加以下内容

s"-Dpidfile.path=/var/run/${packageName.value}/play.pid",
# Add all other startup settings here, too

有关更多详细信息,请参阅 sbt-native-packager 关于 Play 的页面

要阻止 Play 创建 PID,只需将属性设置为 /dev/null

-Dpidfile.path=/dev/null

有关替换的完整列表,请仔细查看 自定义 Java 服务器文档自定义 Java 应用程序文档

§发布到 Maven(或 Ivy)存储库

您也可以将您的应用程序发布到 Maven 仓库。这将发布包含您的应用程序的 JAR 文件以及相应的 POM 文件。

您需要在您的 build.sbt 文件中配置您要发布到的仓库。

publishTo := Some(
  "My resolver".at("https://mycompany.com/repo")
)

credentials += Credentials(
  "Repo",
  "https://mycompany.com/repo",
  "admin",
  "admin123"
)

然后在 Play 控制台中,使用 publish 任务。

[my-first-app] $ publish

查看 sbt 文档 以获取有关解析器和凭据定义的更多信息。

§在本地运行生产服务器

在某些情况下,您可能不想创建完整的发布包,实际上您可能希望从项目的源目录运行您的应用程序。这需要服务器上安装 sbt,并且可以使用 stage 任务完成。

$ sbt clean stage

您将看到类似以下内容

$ sbt
[info] Loading global plugins from /Users/play-developer/.sbt/1.0/plugins
[info] Loading project definition from /Users/play-developer/my-first-app/project
[info] Set current project to my-first-app (in build file:/Users/play-developer/my-first-app/)
[my-first-app] $ stage
[info] Updating {file:/Users/play-developer/my-first-app/}root...
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-sources.jar ...
[info] Done packaging.
[info] Wrote /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT.pom
[info] Resolving jline#jline;2.12.2 ...
[info] Done updating.
[info] Main Scala API documentation to /Users/play-developer/my-first-app/target/scala-2.13/api...
[info] Compiling 8 Scala sources and 1 Java source to /Users/play-developer/my-first-app/target/scala-2.13/classes...
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-web-assets.jar ...
[info] Done packaging.
model contains 21 documentable templates
[info] Main Scala API documentation successful.
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT.jar ...
[info] Done packaging.
[info] Packaging /Users/play-developer/my-first-app/target/scala-2.13/my-first-app_2.13-1.0-SNAPSHOT-sans-externalized.jar ...
[info] Done packaging.
[success] Total time: 8 s, completed Feb 6, 2017 2:11:10 PM
[my-first-app] $

这将清理并编译您的应用程序,检索所需的依赖项并将它们复制到 target/universal/stage 目录。它还会创建一个 bin/<start> 脚本,其中 <start> 是项目的名称。该脚本在 Unix 风格的系统上运行 Play 服务器,并且还有一个相应的 bat 文件用于 Windows。

例如,要从项目文件夹启动项目 my-first-app 的应用程序,您可以

$ target/universal/stage/bin/my-first-app -Dplay.http.secret.key=ad31779d4ee49d5ad5162bf1429c32e2e9933f3b

您也可以从命令行指定生产环境的不同配置文件

$ target/universal/stage/bin/my-first-app -Dconfig.file=/full/path/to/conf/application-prod.conf

§运行测试实例

Play 提供了一个方便的实用程序,用于在生产模式下运行测试应用程序。

注意: 这不适用于生产环境。

要在生产模式下运行应用程序,请运行 runProd

[my-first-app] $ runProd

§使用 sbt assembly 插件

虽然没有官方支持,但 sbt assembly 插件可用于打包和运行 Play 应用程序。这将生成一个 jar 作为输出工件,并允许您使用 java 命令直接执行它。

要使用它,请将对插件的依赖项添加到您的 project/plugins.sbt 文件中

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.4")

现在将以下配置添加到您的 build.sbt

assembly / mainClass := Some("play.core.server.ProdServerStart")
assembly / fullClasspath += Attributed.blank(PlayKeys.playPackageAssets.value)

assembly / assemblyMergeStrategy := {
  case manifest if manifest.contains("MANIFEST.MF") =>
    // We don't need manifest files since sbt-assembly will create
    // one with the given settings
    MergeStrategy.discard
  case referenceOverrides if referenceOverrides.contains("reference-overrides.conf") =>
    // Keep the content for all reference-overrides.conf files
    MergeStrategy.concat
  case x =>
    // For all the other files, use the default sbt-assembly merge strategy
    val oldStrategy = (assembly / assemblyMergeStrategy).value
    oldStrategy(x)
}

现在您可以通过运行 sbt assembly 来构建工件,并通过运行以下命令来运行您的应用程序

$ java -Dplay.http.secret.key=ad31779d4ee49d5ad5162bf1429c32e2e9933f3b -jar target/scala-2.XX/<yourprojectname>-assembly-<version>.jar

当然,您需要替换正确的项目名称、版本和 Scala 版本。

下一步:生产配置


发现此文档中的错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?转到 我们的社区论坛 与社区开始对话。