在单机模式下,Docker中的Keycloak服务器无法启动?

12

正如标题所示,这更多是一个问题记录。我试图按照Keycloak Docker服务器镜像的README文件中的指令操作,但遇到了一些问题。

拉取镜像后,以下命令启动独立实例失败。

docker run jboss/keycloak

错误栈跟踪:

-b 0.0.0.0
=========================================================================

  Using PostgreSQL database

=========================================================================

...

04:45:06,084 INFO  [io.smallrye.metrics] (MSC service thread 1-5) Converted [2] config entries and added [4] replacements
04:45:06,096 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 33) WFLYCTL0013: Operation ("add") failed - address: ([
    ("subsystem" => "datasources"),
    ("data-source" => "KeycloakDS")
]) - failure description: "WFLYCTL0113: '' is an invalid value for parameter user-name. Values must have a minimum length of 1 characters"
...
Caused by: java.lang.RuntimeException: Failed to connect to database
    at org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory.getConnection(DefaultJpaConnectionProviderFactory.java:382)
...
Caused by: javax.naming.NameNotFoundException: datasources/KeycloakDS -- service jboss.naming.context.java.jboss.datasources.KeycloakDS
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:106)
...

我想知道它如何使用PostgreSQL数据库,并且假设它可能会自己启动数据库实例。 但是错误看起来像是连接数据库有问题。

更改为嵌入式H2 DB使其工作。

docker run -e DB_VENDOR="h2" --name docker-keycloak-h2 jboss/keycloak

docker-entrypoint.sh 文件显示它使用以下逻辑来确定使用哪个DB。

if (getent hosts postgres &>/dev/null); then
        export DB_VENDOR="postgres"
...

在流程的更下方,这个change-database.cli文件表明它实际上需要一个正在运行的PostgreSQL实例来使用。

connection-url=jdbc:postgresql://${env.DB_ADDR:postgres}:${env.DB_PORT:5432}/${env.DB_DATABASE:keycloak}${env.JDBC_PARAMS:}

所以我开始思考PostgreSQL最初是如何被选为默认数据库的。在运行的Keycloak Docker容器中执行以下命令,发现了一些有趣的事情。


[root@71961b81189c bin]# getent hosts postgres
69.172.201.153  postgres.mbox.com
[root@71961b81189c bin]# echo $?
0

不确定这个postgres.mbox.com是什么,但显然它不是一个通过getent解析的预期PostgreSQL服务器。也不确定这是否是最近的Linux问题。容器中/etc/nsswitch.conf文件中的名称服务切换配置文件中的hosts条目如下所示。

hosts:      files dns myhostname

正是dns数据源将postgres解析为postgres.mbox.com


这就是为什么DB供应商确定逻辑失败,最终导致容器启动失败。截至此篇文章发布之日,此自述文件中的说明已不起作用。

以下是正确启动使用PostgreSQL作为数据库的Keycloak服务器的工作命令。

docker network create keycloak-network

docker run -d --name postgres --net keycloak-network -e POSTGRES_DB=keycloak -e POSTGRES_USER=keycloak -e POSTGRES_PASSWORD=password postgres

docker run --name docker-keycloak-postgres --net keycloak-network -e DB_USER=keycloak -e DB_PASSWORD=password jboss/keycloak

遇到了同样的问题。然而,您提到的最后一个docker run命令可以正常工作。谢谢! - jwi
1
@jwi 是的,这是因为启动脚本可以检测到正在运行的 postgres 实例。 - Ruifeng Ma
非常感谢您的解决方法 :) - Tim J
3个回答

11
我遇到了相同的问题。事实证明,解决方案的关键是缺少参数 "DB_USER=keycloak"。
应用程序尝试使用用户名“”对数据库进行身份验证。这是第一个错误消息指示的。
WFLYCTL0113: '' is an invalid value for parameter user-name

可能4.x和5.0.0版本将默认用户名设置为“keycloak”,但在6.0.0中不再是这种情况。

将参数DB_USER=keycloak添加到环境变量列表后,keycloak可以顺利启动。


1
我觉得这是一个不同的问题。要解决原帖中提到的确切问题,我们只需要明确指定要使用的数据库,而不是让Keycloak去检查。 - Ruifeng Ma
这个评论帮助了我解决了版本3.4.3.Final的问题。谢谢。 - Fernando S. Kroes

1
现在这个问题不再存在了。我投票关闭这个问题。

@AksimElnik,我在原帖中提供了一种解决方法。你可以尝试使用它来避免这个问题。 - Ruifeng Ma

1
我对这个问题也有一个有趣的观察,即使在7.0.0版本中也是如此。与作者提到的一样,如果主机可以解析,则选择postgres。
$ getent hosts postgres
$ 92.242.140.21

我注意到的是,如果我在ping命令中输入任何奇怪的东西,甚至是foobar,它都会解析为相同的IP地址。例如:

$ ping foobar
$ PING foobar (92.242.140.21): 56 data bytes 

似乎我的ISP将所有内容都发送到一个公共的终端空间。我通过使用-e DB_VENDOR=h2来选择h2数据库解决了问题,然后没有出现任何问题。或者,您始终可以启动自己的postgres版本,或者指向一个合法的端点。(不要使用由您的ISP提供的虚假DNS错误处理)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接