文档

§部署到 Heroku

Heroku 是一个云应用程序平台 - 一种构建和部署 Web 应用程序的方式。

入门

  1. 安装 Heroku 工具带
  2. 注册 Heroku 帐户

有两种部署到 Heroku 的方法

§部署到远程 Git 仓库

§将您的应用程序存储在 git 中

$ git init
$ git add .
$ git commit -m "init"

§在 Heroku 上创建一个新应用程序

$ heroku create
Creating warm-frost-1289... done, stack is cedar-14
http://warm-frost-1289.herokuapp.com/ | [email protected]:warm-frost-1289.git
Git remote heroku added

这将为您的应用程序提供一个新的应用程序,该应用程序具有 HTTP(和 HTTPS)端点和 Git 端点。Git 端点在您的 Git 仓库配置中设置为名为 heroku 的新远程。

§部署您的应用程序

要将您的应用程序部署到 Heroku,请使用 Git 将其推送到 heroku 远程仓库

$ git push heroku main
Counting objects: 93, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (84/84), done.
Writing objects: 100% (93/93), 1017.92 KiB | 0 bytes/s, done.
Total 93 (delta 38), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Play 2.x - Scala app detected
remote: -----> Installing OpenJDK 1.8... done
remote: -----> Priming Ivy cache (Scala-2.11, Play-2.4)... done
remote: -----> Running: sbt compile stage
...
remote: -----> Dropping ivy cache from the slug
remote: -----> Dropping sbt boot dir from the slug
remote: -----> Dropping compilation artifacts from the slug
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing... done, 93.3MB
remote: -----> Launching... done, v6
remote:        https://warm-frost-1289.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/warm-frost-1289.git
* [new branch]      main -> main

Heroku 将运行 sbt stage 来准备您的应用程序。在第一次部署时,所有依赖项都将被下载,这需要一段时间才能完成(但它们将在以后的部署中被缓存)。

如果您使用的是 RequireJS 并且发现您的应用程序在此步骤中挂起

[info] Optimizing JavaScript with RequireJS

然后尝试按照 Heroku 开发中心上的 使用 Node.js 为 Play 和 Scala 应用程序执行 JavaScript 优化 中的步骤操作。这将大大提高 Javascript 引擎的性能。

§检查您的应用程序是否已部署

现在,让我们检查应用程序进程的状态

$ heroku ps
=== web (Free): `target/universal/stage/bin/sample-app -Dhttp.port=${PORT}`
web.1: up 2015/01/09 11:27:51 (~ 4m ago)

Web 进程正在运行。我们可以查看日志以获取更多信息

$ heroku logs
2015-07-13T20:44:47.358320+00:00 heroku[web.1]: Starting process with command `target/universal/stage/bin/myapp -Dhttp.port=${PORT}`
2015-07-13T20:44:49.750860+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx384m -Xss512k -Dfile.encoding=UTF-8
2015-07-13T20:44:52.297033+00:00 app[web.1]: [warn] application - Logger configuration in conf files is deprecated and has no effect. Use a logback configuration file instead.
2015-07-13T20:44:54.960105+00:00 app[web.1]: [info] p.a.l.c.ActorSystemProvider - Starting application default Pekko system: application
2015-07-13T20:44:55.066582+00:00 app[web.1]: [info] play.api.Play$ - Application started (Prod)
2015-07-13T20:44:55.445021+00:00 heroku[web.1]: State changed from starting to up
2015-07-13T20:44:55.330940+00:00 app[web.1]: [info] p.c.s.PekkoHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
...

我们也可以像处理普通文件一样跟踪日志。这对于调试很有用。

$ heroku logs -t --app warm-frost-1289
2015-07-13T20:44:47.358320+00:00 heroku[web.1]: Starting process with command `target/universal/stage/bin/myapp -Dhttp.port=${PORT}`
2015-07-13T20:44:49.750860+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx384m -Xss512k -Dfile.encoding=UTF-8
2015-07-13T20:44:52.297033+00:00 app[web.1]: [warn] application - Logger configuration in conf files is deprecated and has no effect. Use a logback configuration file instead.
2015-07-13T20:44:54.960105+00:00 app[web.1]: [info] p.a.l.c.ActorSystemProvider - Starting application default Pekko system: application
2015-07-13T20:44:55.066582+00:00 app[web.1]: [info] play.api.Play$ - Application started (Prod)
2015-07-13T20:44:55.445021+00:00 heroku[web.1]: State changed from starting to up
2015-07-13T20:44:55.330940+00:00 app[web.1]: [info] p.c.s.PekkoHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000
...

看起来不错。现在我们可以通过运行以下命令访问应用程序

$ heroku open

§故障排除

如果您的应用程序包含一个 build.gradle 文件,Heroku 会检测到它并尝试将您的应用程序构建为 Gradle 项目,而不是 Scala sbt 项目。您可以通过运行以下命令强制 Heroku 使用 sbt

$ heroku buildpacks:set heroku/scala

Scala 构建包 将使用您仓库中的 build.sbt 文件来构建应用程序。

§部署使用最新 Java 版本的应用程序

Heroku 默认使用 OpenJDK 8 运行 Java 应用程序。它无法自动确定是否需要其他版本,因此部署使用较新 Java 版本的应用程序会导致服务器上的编译错误。如果您使用的是比 Java 8 更新的版本,则应在项目根目录中的 system.properties 文件中声明它,例如

java.runtime.version=11

有关更多详细信息,请参阅 heroku 文档

§使用 sbt-heroku 插件部署

Heroku sbt 插件利用 API 来提供将预打包的独立 Web 应用程序直接部署到 Heroku。对于编译时间很长或需要从持续集成服务器(如 Travis CI 或 Jenkins)部署的应用程序,这可能是一种首选方法。

§添加插件

要将 Heroku sbt 插件 包含在您的项目中,请将以下内容添加到您的 project/plugins.sbt 文件中

addSbtPlugin("com.heroku" % "sbt-heroku" % "2.0.0")

接下来,我们必须配置插件将部署到的 Heroku 应用程序的名称。但首先,创建一个新的应用程序。安装 Heroku 工具带并运行创建命令。

$ heroku create
Creating obscure-sierra-7788... done, stack is cedar-14
http://obscure-sierra-7788.herokuapp.com/ | [email protected]:obscure-sierra-7788.git

现在将类似以下内容添加到您的 build.sbt 中,但将“obscure-sierra-7788”替换为您创建的应用程序的名称(或者如果您在本地使用 Git,则可以跳过此步骤)。

Compile / herokuAppName := "obscure-sierra-7788"

sbt-heroku 项目的文档包含有关 配置插件执行 的详细信息。

§使用插件部署

添加插件后,您可以通过运行以下命令部署到 Heroku

$  sbt stage deployHeroku
...
[info] -----> Packaging application...
[info]        - app: obscure-sierra-7788
[info]        - including: target/universal/stage/
[info] -----> Creating build...
[info]        - file: target/heroku/slug.tgz
[info]        - size: 30MB
[info] -----> Uploading slug... (100%)
[info]        - success
[info] -----> Deploying...
[info] remote:
[info] remote: -----> Fetching custom tar buildpack... done
[info] remote: -----> sbt-heroku app detected
[info] remote: -----> Installing OpenJDK 1.8... done
[info] remote: -----> Discovering process types
[info] remote:        Procfile declares types -> console, web
[info] remote:
[info] remote: -----> Compressing... done, 78.9MB
[info] remote: -----> Launching... done, v6
[info] remote:        https://obscure-sierra-7788.herokuapp.com/ deployed to Heroku
[info] remote:
[info] -----> Done
[success] Total time: 90 s, completed Aug 29, 2014 3:36:43 PM

您可以通过运行以下命令访问您的应用程序

$ heroku open -a obscure-sierra-7788

您可以通过运行以下命令查看应用程序的日志

$ heroku logs -a obscure-sierra-7788

请注意,如果您使用的是 Git,则可以省略上面的 -a 选项,因为应用程序
名称将从您在配置中添加的 Git 远程仓库中检测到。
运行了 heroku create 命令。

§连接到数据库

Heroku 通过 Heroku 附加组件 提供了许多关系型和 NoSQL 数据库。在 Heroku 上的 Play 应用程序会自动配置一个 Heroku Postgres 数据库。要配置 Play 应用程序以使用 Heroku Postgres 数据库,首先将 PostgreSQL JDBC 驱动程序添加到应用程序依赖项(build.sbt)中。

libraryDependencies += "org.postgresql" % "postgresql" % "9.4-1201-jdbc41"

然后在项目的根目录中创建一个名为 Procfile(以大写字母“P”开头)的新文件,其中包含以下内容(将 myapp 替换为您的项目名称)

web: target/universal/stage/bin/myapp -Dhttp.port=${PORT} -Dplay.evolutions.db.default.autoApply=true -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=${DATABASE_URL}

这指示 Heroku 对于名为 web 的进程,它将运行 Play 并覆盖 play.evolutions.db.default.autoApplydb.default.driverdb.default.url 配置参数。请注意,Procfile 命令的长度不能超过 255 个字符。或者,可以使用 生产配置 页面中提到的 -Dconfig.resource=-Dconfig.file=

此外,请注意 DATABASE_URL 采用平台无关的格式

vendor://username:password@host:port/db

如果您使用的是内置的数据库连接池之一,Play 会自动将其转换为 JDBC URL。但是,其他数据库库和框架(如 Slick 或 Hibernate)可能不支持此格式。
如果是这种情况,您可以尝试在配置中使用 动态 JDBC_DATABASE_URL 来代替 DATABASE_URL,如下所示

db.default.url=${?JDBC_DATABASE_URL}
db.default.username=${?JDBC_DATABASE_USERNAME}
db.default.password=${?JDBC_DATABASE_PASSWORD}

请注意,Heroku 实际上并不需要创建 Procfile,因为 Heroku 会在 Play 应用程序的 conf 目录中查找 application.conf 文件,以确定它是一个 Play 应用程序。

§进一步学习资源

下一步:部署到 Cloud Foundry


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