问题现象
- 使用
docker
部署keycloak
服务,使用docker-compose
进行配置管理,配置如下:
keycloak:
image: jboss/keycloak:16.1.0
container_name: keycloak
command:
[
'-b',
'0.0.0.0',
'-Dkeycloak.migration.action=import',
'-Dkeycloak.migration.provider=dir',
'-Dkeycloak.migration.dir=/opt/jboss/keycloak/realm-config',
'-Dkeycloak.migration.strategy=IGNORE_EXISTING',
'-Djboss.socket.binding.port-offset=1000',
'-Dkeycloak.profile.feature.upload_scripts=enabled',
]
volumes:
- /etc/localtime:/etc/localtime
depends_on:
- postgresql
environment:
- KEYCLOAK_USER=admin
- KEYCLOAK_PASSWORD=admin
- DB_VENDOR=postgres
- DB_ADDR=postgresql:5432
- DB_DATABASE=keycloak
- DB_USER=postgres
- DB_PASSWORD=xxxxxxx
- TZ=Asia/Shanghai
ports:
- 9080:9080
restart: always
- 使用
docker-compose up -d
创建容器启动,是没有问题的,启动成功后可以使用ip:9080
端口访问,启动成功会出现如下日志
- 如果
keycloak
服务,在容器启动过程中(启动到一半)异常关闭,就会卡死无法启动,后续使用docker restart keycloak
也没用,会一直卡死在这一行User with username 'admin' already added to '/opt/jboss/keycloak/standalone/configuration/keycloak-add-user.json'
- 使用
docker exec -it keycloak /bin/bash
进入容器,找到这个位置/opt/jboss/keycloak/standalone/configuration/
,也没看到这个文件
- 搜索网上的解决方案(包括
Stack Overflow
相关问题里的最高赞回答),大多数都是:停止容器,删除容器,重新创建重启启动 - 删除容器重建确实能解决问题,但是这样很不优雅。而且如果
keycloak
没有使用数据库,数据还有丢失
分析和解决
- 这个问题官方其实有问题帖: Related issue,可能因为网络问题打不开,继续看我的文章就行
- 贴下
Stack Overflow
原贴,解决方案主要来源于这个帖子:keycloak-8-user-with-username-admin-already-added - 继续看里面的回复,看到一个用户
Zmey
回复This happens when Keycloak is interrupted during boot. After this, command which attempts to add admin user starts to fail. In Keycloak 7 this wasn't fatal, but in 8.0.1 this line was added to /opt/jboss/tools/docker-entrypoint.sh which aborts the entire startup script:
,渣翻下为如下
这个问题发生在Keycloak启动过程中被中断的情况下。在此之后,试图添加管理员用户的命令将开始失败。在Keycloak 7中,这并不致命,但在8.0.1中,将此行添加到/opt/jboss/tools/docker-entrypoint.sh中会使整个启动脚本中止
- 继续去了解keycloak启动过程,会发现依赖这个脚本
docker-entrypoint.sh
,而上面的报错信息会中止该脚本运行,从而中止启动过程,核心其实是这一句set -eou pipefail
- 在这个用户后面,一位大佬
Bruno Ranschaert
回复了下,给了解决方法You can repair the failing container by first copying this file from the container to your local machine "docker cp keycloak:/opt/jboss/tools/docker-entrypoint.sh ." Comment out the line "set -eou pipefail", copy it back into the container using "docker cp docker-entrypoint.sh keycloak:/opt/jboss/tools/" and restart the container. After a clean startup/shutdown, you could restore (uncomment) this line again
,渣翻一下如下:
你可以通过将该文件从容器复制到本地机器来修复故障容器:“docker cp keycloak:/opt/jboss/tools/docker-entrypoint.sh .”将其注释掉 “set -eou pipefail” 这一行,然后使用“docker cp docker-entrypoint.sh keycloak:/opt/jboss/tools/”将其复制回容器,并重新启动容器。在干净的启动/关闭之后,你可以再次恢复(取消注释)这一行。“
- 这个修改和拷贝的方式,虽然有用,但是对于我来说还需要改进下,因为如果容器删除,或者在新的服务器部署,这个操作还要来一遍
- 思路很简单,直接把这个文件映射出来,修改好,后续无论是删除容器重建还是新服务器部署,把文件放到对应位置即可
- 使用
docker cp
命令将docker-entrypoint.sh
拷贝出来,注释掉 “set -eou pipefail” 这一行,放到我们的服务器的某个位置(我放在了./volumes/keycloak-customized/
下) - 然后修改docker-compose 配置,在volumes增加一个映射,如下:
volumes:
- ./volumes/keycloak-customized/docker-entrypoint.sh:/opt/jboss/tools/docker-entrypoint.sh
- 至此结束,看到这里的小伙伴,如果对你有帮助,欢迎来一个评论交流下或给个赞