部署到 Heroku
在本指南中,您将学习如何将基于 Quarkus 的 Web 应用程序作为 Web dyno 部署到 Heroku。
本指南涵盖
-
更新 Quarkus HTTP 端口
-
安装 Heroku CLI
-
将应用程序部署到 Heroku
-
将应用程序作为容器镜像部署到 Heroku
-
使用 Docker
-
使用 Podman
-
-
将原生应用程序作为容器镜像部署到 Heroku
先决条件
要完成本指南,您需要
-
所有方式大约需要 1 小时
-
一个 IDE
-
已安装 JDK 17+ 并正确配置了
JAVA_HOME
-
Apache Maven 3.9.9
-
如果您想使用它,可以选择 Quarkus CLI
-
一个 Heroku 帐户。您至少需要一个 Eco 帐户才能部署应用程序。
简介
Heroku 是一个平台即服务 (PaaS),使开发人员能够在云中完全构建、运行和运营应用程序。 它支持多种语言,如 Java、Ruby、Node.js、Scala、Clojure、Python、PHP 和 Go。 此外,它还提供了一个容器注册表,可用于部署预构建的容器镜像。
可以使用不同的方式使用 Heroku 运行 Quarkus 应用程序
-
作为在 Heroku 环境定义的容器中运行的普通 Java 程序
-
作为在 Quarkus 构建过程定义的容器中运行的容器化 Java 程序
-
作为在 Quarkus 构建过程定义的容器中运行的容器化原生程序
所有这三种方法都需要注意 Heroku 分配给它的用于处理流量的端口。 幸运的是,有一个动态配置属性可以实现这一点。
通用项目设置
本指南将采用使用 Quarkus 工具创建的简单应用程序作为输入
对于 Windows 用户
-
如果使用 cmd,(不要使用反斜杠
\
并将所有内容放在同一行上) -
如果使用 Powershell,请将
-D
参数用双引号括起来,例如"-DprojectArtifactId=getting-started-with-heroku"
此命令将在 getting-started-with-heroku
目录中创建一个新的 REST 应用程序。
让我们将此应用程序创建为一个 Git 存储库
-
更改到应用程序目录:
cd getting-started-with-heroku
。 -
初始化一个新的 Git 存储库:
git init -b main
。 -
将所有文件添加到存储库:
git add .
。 -
提交文件:
git commit -a -m 'Initial copy of getting-started'
。
Heroku 可以对存储库中的更改做出反应,运行 CI 并在您的代码更改时重新部署您的应用程序。 因此,我们从一个有效的存储库开始。
另外,请确保您的 Heroku CLI 工作正常
heroku --version
heroku login
准备 Quarkus HTTP 端口
Heroku 选择一个随机端口并将其分配给最终运行您的 Quarkus 应用程序的容器。 该端口作为环境变量在 $PORT
下可用。 在所有部署方案中,使 Quarkus 了解它的最简单方法是使用以下配置
quarkus.http.port=${PORT:8080}
这可以理解为:“如果定义了 $PORT
变量,则侦听该端口,否则像往常一样侦听 8080。” 运行以下命令将其添加到您的 application.properties
echo "quarkus.http.port=\${PORT:8080}" >> src/main/resources/application.properties
git commit -am "Configure the HTTP Port."
部署存储库并在 Heroku 上构建
第一种变体使用 Quarkus Maven 构建来创建 quarkus-app 应用程序结构,其中包含可运行的“fast-jar”以及 Heroku 构建基础设施中所需的所有库,然后部署该结果,另一种变体使用本地构建过程来创建优化的容器。
对于第一种变体,您的应用程序的根目录中需要两个额外的文件
-
system.properties
用于配置 Java 版本 -
Procfile
用于配置 Heroku 如何启动您的应用程序
Quarkus 需要 JDK 17,因此我们首先指定它
echo "java.runtime.version=17" >> system.properties
git add system.properties
git commit -am "Configure the Java version for Heroku."
我们将部署一个 Web 应用程序,因此我们需要在 Heroku Procfile
中配置 web
类型,如下所示
echo "web: java \$JAVA_OPTS -jar target/quarkus-app/quarkus-run.jar" >> Procfile
git add Procfile
git commit -am "Add a Procfile."
您的应用程序应该已经可以通过存储库根目录中的 heroku local web
运行。 您需要在之前运行 mvn package
才能成功创建可运行的 jar。
现在让我们在您的帐户中创建一个应用程序并将该存储库部署到它
heroku create
这将在您的 Heroku 帐户中创建一个远程存储库,并且它还应该已将一个 heroku 远程 URL 添加到您的本地存储库,您可以使用 git remote -v
查看它
starksm@Scotts-Mac-Studio getting-started % git remote -v
heroku https://git.heroku.com/young-shelf-58876.git (fetch)
heroku https://git.heroku.com/young-shelf-58876.git (push)
现在您可以将您的应用程序推送到 Heroku 并在浏览器中打开它。
git push heroku main
heroku open hello
该应用程序将具有一个生成的 URL,并且终端应该输出该 URL。 heroku open hello
打开您的默认浏览器以使用 '/hello' 上下文访问您的新应用程序。 该页面应输出文本“hello”。
要通过 curl 访问 REST 端点,请从 heroku info 命令获取应用程序 URL
heroku info | grep "Web URL:"
APP_NAME=<https url info>
curl $APP_NAME/hello
当然,您也可以使用 Heroku CLI 将此存储库连接到您的 GitHub 帐户,但这不在本指南的范围之内。
作为容器部署
推送整个容器的优点是我们可以完全控制其内容,甚至可以选择部署一个在 GraalVM 上运行本机可执行文件的容器。
首先,登录到 Heroku 的容器注册表
heroku container:login
我们需要向我们的项目添加一个扩展,以添加构建容器镜像的功能
quarkus extension add container-image-docker
./mvnw quarkus:add-extension -Dextensions='container-image-docker'
./gradlew addExtension --extensions='container-image-docker'
然后,让我们提交此更改
git add pom.xml
git commit -am "Add container-image-docker extension."
我们将要构建的镜像需要根据 Heroku 的注册表和部署进行命名。 我们通过 heroku info
获取生成的名称并将其传递给(本地)构建
APP_NAME=`heroku info | grep "=== .*" |sed "s/=== //"`
./mvnw clean package\
-Dquarkus.container-image.build=true\
-Dquarkus.container-image.group=registry.heroku.com/$APP_NAME\
-Dquarkus.container-image.name=web\
-Dquarkus.container-image.tag=latest
推送和发布镜像
您现在可以推送镜像并发布它。
初始推送相当大,因为需要传输镜像的所有层。 以下推送将更小。 |
通过 Docker 推送
安装 Docker 后,这些步骤很简单
docker push registry.heroku.com/$APP_NAME/web
heroku stack:set container
heroku container:release web --app $APP_NAME
通过 Podman 推送
当您想使用 Podman 作为 Docker 的替代品时,您会遇到一些问题,因为 Heroku CLI 依赖于 Docker 并且不支持 OCI 格式。 但是,这些问题有可能的解决方案。
找不到 docker,请确保已安装 docker。
问题显然是 heroku-cli 找不到 docker。 这很容易解决,因为 podman cli 与 docker 兼容。 我们只需要创建一个从 podman 到 docker 的符号链接
|
Error writing manifest: Error uploading manifest latest to registry.heroku.com/$APP_NAME/web: unsupported
为了通过 Podman 和 Heroku CLI 以所需的格式(v2s2 - Docker Image Manifest Version 2, Schema 2)推送和发布我们的应用程序,我们必须使用一种解决方法,而不是执行正常的 podman 推送(OCI 格式)。 还需要 skopeo。
|
在容器内部署为原生应用程序
当我们以容器形式部署我们的应用程序时,我们采取的最大优势是以原生编译的应用程序部署容器。 为什么? 因为当没有传入流量时,Heroku 将停止或休眠该应用程序。 原生应用程序将从休眠状态更快地唤醒。
该过程几乎相同。 我们选择在本地容器中编译本机镜像,这样我们就不必处理在本地安装 GraalVM 的问题
APP_NAME=`heroku info | grep "=== .*" |sed "s/=== //"`
./mvnw clean package \
-Dquarkus.container-image.build=true \
-Dquarkus.container-image.group=registry.heroku.com/$APP_NAME \
-Dquarkus.container-image.name=web \
-Dquarkus.container-image.tag=latest \
-Dnative \
-Dquarkus.native.container-build=true
之后,再次使用 Docker 或 Podman(请参见上文)推送和发布,并检查日志。