使用 Heroku 的 Quarkus 数据源
Posted
技术标签:
【中文标题】使用 Heroku 的 Quarkus 数据源【英文标题】:Quarkus datasource with Heroku 【发布时间】:2020-07-15 11:18:55 【问题描述】:我正在尝试在 Heroku 上部署我的 Quarkus 应用。它工作正常,但我需要用固定值指定数据源参数。因为 Heroku 可能会旋转这个参数,所以这不是一个好主意。
在 Quarkus 中,我需要 application.properties
中的这 3 个参数:
quarkus.datasource.username
quarkus.datasource.password
quarkus.datasource.jdbc.url
Heroku 只给了我 1 个环境变量 (DATABASE_URL
),它以下列方式定义了一个连接字符串:
postgres://user:pass@server:port/db-name
我知道我可以像这样使用环境变量:
quarkus.datasource.jdbc.url = jdbc:$DATABASE_URL
但我需要拆分变量以提取用户和密码并更改前缀(postgresql 而不是 postgres)。
有人知道如何实现这一目标吗?
【问题讨论】:
嗨@simon-wick,您的问题解决了吗?如果是,请告诉我怎么做。 【参考方案1】:您可以将JDBC_DATABASE_URL
、JDBC_DATABASE_USERNAME
和JDBC_DATABASE_PASSWORD
环境变量用于您的用例。
更多详情,你可以在这里找到文档:https://devcenter.heroku.com/articles/connecting-to-relational-databases-on-heroku-with-java#using-the-jdbc_database_url
【讨论】:
来自文档:The official Heroku buildpacks for Java, Scala, Clojure, and Gradle will attempt to create a JDBC_DATABASE_URL environment variable when a dyno starts up.
我将 quarkus 原生应用程序(docker 镜像)部署到 heroku,我可以强制 heroku 添加 JDBC_DATABASE_USERNAME
和 JDBC_DATABASE_PASSWORD
变量吗?
@tostao 遗憾的是,您不能这样做。 Heroku 在 dyno 启动时使用脚本添加这些 JDBC 环境变量。我们使用我们的官方 JVM 构建包将该脚本打包到您的 slug(图像)中。但是,由于这些构建包是开源的,您可以获取脚本并在自定义 docker 映像中使用它:github.com/heroku/heroku-buildpack-jvm-common/blob/…
我明白了你的意思:我需要安装这个heroku-buildpack-jvm
并且它会工作吗?或者我应该将这个jdbc.sh
脚本添加到我的部署工作中吗?任何示例将不胜感激。【参考方案2】:
我创建了一个 bash 脚本来从 Heroku DATABASE_URL
中提取三个 Quarkus 参数。
它适用于 JVM 和本机版本。
我的application.properties
:
quarkus.datasource.jdbc.url=$DB_JDBC_URL:jdbc-url
quarkus.datasource.username=$DB_JDBC_USER:postgres
quarkus.datasource.password=$DB_JDBC_PASSWORD:postgres
短版
# cut the DATABASE_URL after '@'
export DB_JDBC_URL=jdbc:postgresql://$DATABASE_URL#*@
# substring the DATABASE_URL between '//' and ':'
export DB_JDBC_USER=$(expr $DATABASE_URL : '.*/\([^:]*\):.*')
# substring the DATABASE_URL between ':' and '@'
export DB_JDBC_PASSWORD=$(expr $DATABASE_URL : '.*:\([^@]*\)@.*')
长版
Bash 脚本
使用heroku.sh 文件名将以下脚本保存在项目的根文件夹中。
#!/bin/sh
# =============================================================================
# This script automatically splits the Heroku ENV DATABASE_URL variable
# into the three JDBC variables needed from Quarkus.
#
# It will only do the split if the DB_HEROKU_SPLIT is set to "true".
#
# If you set DB_HEROKU_SPLIT to 'false', you must pass the Quarkus parameters:
# - DB_JDBC_URL;
# - DB_JDBC_USER;
# - DB_JDBC_PASSWORD.
#
# For test purposes, you can set the DB_ECHO_VALUES to 'true' and check if the
# values are correct.
#
# Pattern of DATABASE_URL from Heroku:
# --------------------------------------
# postgres://username:password@host:port/databasename
#
# Pattern of JDBC variables of Quarkus:
# -------------------------------------
# quarkus.datasource.jdbc.url=jdbc:postgresql://host:port/databasename
# quarkus.datasource.username=username
# quarkus.datasource.password=password
#
# =============================================================================
echo DB_HEROKU_SPLIT=[$DB_HEROKU_SPLIT]
# check for 'true' in string (case insensitive)
if [[ "$DB_HEROKU_SPLIT,," == "true" ]]; then
# cut the DATABASE_URL after '@'
export DB_JDBC_URL=jdbc:postgresql://$DATABASE_URL#*@
# substring the DATABASE_URL between '//' and ':'
export DB_JDBC_USER=$(expr $DATABASE_URL : '.*/\([^:]*\):.*')
# substring the DATABASE_URL between ':' and '@'
export DB_JDBC_PASSWORD=$(expr $DATABASE_URL : '.*:\([^@]*\)@.*')
fi
# check for 'true' in string (case insensitive)
if [[ "$DB_ECHO_VALUES,," == "true" ]]; then
echo DATABASE_URL=[$DATABASE_URL]
echo DB_JDBC_URL=[$DB_JDBC_URL]
echo DB_JDBC_USER=[$DB_JDBC_USER]
echo DB_JDBC_PASSWORD=[$DB_JDBC_PASSWORD]
fi
Dockerignore
记得将此文件包含在您的.dockerignore
中:
*
!heroku.sh
!target/*-runner
!target/*-runner.jar
!target/lib/*
!target/quarkus-app/*
Dockerfile.jvm
用这个替换原来的ENTRYPOINT
:
# commands from original Quarkus Dockerfile.jvm file suppressed for breviety
COPY --chown=1001 heroku.sh /deployments/heroku.sh
RUN chmod 540 /deployments/heroku.sh
CMD [ "/bin/bash", "-c" , ". /deployments/heroku.sh && /deployments/run-java.sh" ]
Dockerfile.native
用这个替换原来的CMD
:
# commands from original Quarkus Dockerfile.jvm file suppressed for breviety
COPY --chown=1001 heroku.sh /work/heroku.sh
RUN chmod 540 /work/heroku.sh
CMD ["/bin/bash", "-c", ". ./heroku.sh && ./application", "-Dquarkus.http.host=0.0.0.0"]
Heroku 配置变量
DB_HEROKU_SPLIT
如果您希望 bash 脚本为您提取 Quarkus 数据源变量,请将 DB_HEROKU_SPLIT
添加到 Heroku 的 Config Vars 并将其设置为 true
。
将其设置为false
,您可以在 Heroku Config Vars 中创建 Quarkus 数据源(DB_JDBC_URL、、DB_JDBC_PASSWORD 和 DB_JDBC_PASSWORD),并绕过 bash 脚本直接将它们传递给 Quarkus。
DB_ECHO_VALUES
我还创建了一个DB_ECHO_VALUES
变量,允许您在日志中显示数据源。如果要在屏幕上打印日志,只需将DB_ECHO_VALUES
设置为true即可。
【讨论】:
以上是关于使用 Heroku 的 Quarkus 数据源的主要内容,如果未能解决你的问题,请参考以下文章
在测试我的 Quarkus 应用程序时如何使用内存中的 H2 数据库?
Quarkus 找不到内容类型多部分/表单数据休息客户端的编写器
为啥“Quarkus”选择“Agroal”而不是“HikariCP”作为首选数据源和连接池实现? [关闭]