英文:
Migrations of Keycloak from v16 to v21 doesn't import realms and users
问题
We have dockerized Keycloak v16 and now we would like to migrate to a version v21.
We uses Postgres database and we have inside this database already created realms and users.
When we upgraded to v21, everything works except that Keycloak shows that realms are empty and users as well.
If I inspect the database, all users and realms are still there...
How to tell Keycloak to read old realms and users?
New docker file
FROM quay.io/keycloak/keycloak:21.0.2
COPY themes/ /opt/jboss/keycloak/themes/
ADD ./standalone-ha.xml /opt/jboss/keycloak/standalone/configuration/standalone-ha.xml
standalone-ha.xml
<spi name="connectionsJpa">
<provider name="default" enabled="true">
<properties>
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
<property name="initializeEmpty" value="true"/>
<property name="migrationStrategy" value="update"/>
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
<property name="schema" value="${env.DB_SCHEMA:public}"/>
</properties>
</provider>
</spi>
docker-compose file
keycloak:
image: mykeycloak
environment:
DB_VENDOR: POSTGRES
DB_ADDR: xxxx
DB_DATABASE: keycloak
DB_USER: postgres
DB_SCHEMA: public
DB_PASSWORD: xxxx
KEYCLOAK_ADMIN: xxxx
KEYCLOAK_ADMIN_PASSWORD: xxxx
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth --spi-connections-jpa-legacy-migration-strategy=update
ports:
- 8080:8080
EDIT:
-----------
I figure out that Keycloak is not connecting to a database. I always insert the same realms so I thought that new and old are in the same database.
So the question is how to connect correctly to a Postgres container.
I changed the docker-compose file to:
```plaintext
db:
image: postgres:13.2
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: 'xxx'
# volumes:
# - /Volumes/DATA/docker_volume/pgdata:/var/lib/postgresql/data
keycloak:
depends_on:
- db
image: mykeycloak
environment:
KC_DB: postgres
KC_DB_ADDR: db
KC_DB_DATABASE: keycloak
KC_DB_USER: postgres
KC_DB_SCHEMA: public
KC_DB_PASSWORD: xxx
KEYCLOAK_ADMIN: keycloak_admin
KEYCLOAK_ADMIN_PASSWORD: xxx
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth
ports:
- 8080:8080
Now I get the error:
2023-06-22 10:18:30 2023-06-22 08:18:30,593 WARN [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator] (JPA Startup Thread: keycloak-default) HHH000342: Could not obtain connection to query metadata: org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
2023-06-22 10:18:30 at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:319)
...
我們已經將Keycloak v16容器化,現在我們想要遷移到版本v21。
我們使用的是Postgres數據庫,並且在這個數據庫中已經創建了領域和用戶。
當我們升級到v21時,一切都正常,只是Keycloak顯示領域和用戶是空的。
如果我檢查數據庫,所有的用戶和領域仍然存在...
如何告訴Keycloak讀取舊的領域和用戶?
新的Docker文件
FROM quay.io/keycloak/keycloak:21.0.2
COPY themes/ /opt/jboss/keycloak/themes/
ADD ./standalone-ha.xml /opt/jboss/keycloak/standalone/configuration/standalone-ha.xml
standalone-ha.xml
<spi name="connectionsJpa">
<provider name="default" enabled="true">
<properties>
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
<property name="initializeEmpty" value="true"/>
<property name="migrationStrategy" value="update"/>
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
<property name="schema" value="${env.DB_SCHEMA:public}"/>
</properties>
</provider>
</spi>
docker-compose文件
keycloak:
image: mykeycloak
environment:
DB_VENDOR: POSTGRES
DB_ADDR: xxxx
DB_DATABASE: keycloak
DB_USER: postgres
DB_SCHEMA: public
DB_PASSWORD: xxxx
KEYCLOAK_ADMIN: xxxx
KEYCLOAK_ADMIN_PASSWORD: xxxx
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth --spi-connections-jpa-legacy-migration-strategy=update
ports:
- 8080:8080
編輯:
-----------
我發現Keycloak無法連接到數據庫。我總是插入相同的領域,所以我認為新的和舊的都在同一個數據庫中。
所以問題是如何正確連接到Postgres容器。
我將docker-compose文件更改為:
```plaintext
db:
image: postgres:13.2
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: 'xxx'
# volumes:
# - /Volumes/DATA/docker_volume/pgdata:/var/lib/postgresql/data
keycloak:
depends_on:
- db
image:
<details>
<summary>英文:</summary>
We have dockerized Keycloak v16 and now we would like to migrate to a version v21.
We uses Postgres database and we have inside this database already created realms and users.
When we upgraded to a v21 everything works except that Keycloak shows that realms are empty and users as well.
If I inspect database, all users and realms are still there...
How to tell Keycloak to read old realms and users?
New docker file
FROM quay.io/keycloak/keycloak:21.0.2
COPY themes/ /opt/jboss/keycloak/themes/
ADD ./standalone-ha.xml /opt/jboss/keycloak/standalone/configuration/standalone-ha.xm
standalone-ha.xml
<spi name="connectionsJpa">
<provider name="default" enabled="true">
<properties>
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
<property name="initializeEmpty" value="true"/>
<property name="migrationStrategy" value="update"/>
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
<property name="schema" value="${env.DB_SCHEMA:public}"/>
</properties>
</provider>
</spi>
docker-compose file
keycloak:
image: mykeycloak
environment:
DB_VENDOR: POSTGRES
DB_ADDR: xxxx
DB_DATABASE: keycloak
DB_USER: postgres
DB_SCHEMA: public
DB_PASSWORD: xxxx
KEYCLOAK_ADMIN: xxxx
KEYCLOAK_ADMIN_PASSWORD: xxxx
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth --spi-connections-jpa-legacy-migration-strategy=update
ports:
- 8080:8080
EDIT:
-----------
I figure out that Keycloak is not connecting to a database. I always insert the same realms so I though that new and old are in same database.
So the question is how to connect correctly to a Postgres container.
I change the docker-compose file to a
db:
image: postgres:13.2
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: 'xxx'
# volumes:
# - /Volumes/DATA/docker_volume/pgdata:/var/lib/postgresql/data
keycloak:
depends_on:
- db
image: mykeycloak
environment:
KC_DB: postgres
KC_DB_ADDR: db
KC_DB_DATABASE: keycloak
KC_DB_USER: postgres
KC_DB_SCHEMA: public
KC_DB_PASSWORD: xxx
KEYCLOAK_ADMIN: keycloak_admin
KEYCLOAK_ADMIN_PASSWORD: xxx
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth
ports:
- 8080:8080
now I get the error
2023-06-22 10:18:30 2023-06-22 08:18:30,593 WARN [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator] (JPA Startup Thread: keycloak-default) HHH000342: Could not obtain connection to query metadata: org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
2023-06-22 10:18:30 at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:319)
2023-06-22 10:18:30 at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
2023-06-22 10:18:30 at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:247)
2023-06-22 10:18:30 at org.postgresql.Driver.makeConnection(Driver.java:434)
2023-06-22 10:18:30 at org.postgresql.Driver.connect(Driver.java:291)
2023-06-22 10:18:30 at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
2023-06-22 10:18:30 at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)
2023-06-22 10:18:30 at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:103)
2023-06-22 10:18:30 at org.postgresql.xa.PGXADataSource.getXAConnection(PGXADataSource.java:49)
2023-06-22 10:18:30 at org.postgresql.xa.PGXADataSource.getXAConnection(PGXADataSource.java:35)
2023-06-22 10:18:30 at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:232)
2023-06-22 10:18:30 at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:536)
2023-06-22 10:18:30 at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:517)
2023-06-22 10:18:30 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
2023-06-22 10:18:30 at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:75)
2023-06-22 10:18:30 at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
2023-06-22 10:18:30 at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
2023-06-22 10:18:30 at java.base/java.lang.Thread.run(Thread.java:833)
2023-06-22 10:18:30 Caused by: java.net.ConnectException: Connection refused
2023-06-22 10:18:30 at java.base/sun.nio.ch.Net.pollConnect(Native Method)
2023-06-22 10:18:30 at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
2023-06-22 10:18:30 at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542)
2023-06-22 10:18:30 at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597)
2023-06-22 10:18:30 at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
2023-06-22 10:18:30 at java.base/java.net.Socket.connect(Socket.java:633)
2023-06-22 10:18:30 at org.postgresql.core.PGStream.createSocket(PGStream.java:241)
2023-06-22 10:18:30 at org.postgresql.core.PGStream.<init>(PGStream.java:98)
2023-06-22 10:18:30 at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:109)
2023-06-22 10:18:30 at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:235)
2023-06-22 10:18:30 ... 17 more
2023-06-22 10:18:30
</details>
# 答案1
**得分**: 0
# 对于仍然遇到这个问题的人:
我发现这个 Docker 镜像在连接到外部的 Postgres 数据库时没有报错,而是默默地失败了。
因为没有错误,我以为连接已经建立,但我错了。
### 在新版本中,添加了新的环境参数
连接 Postgres 数据库到 Keycloak Docker 镜像的正确参数是:
```yaml
keycloak:
depends_on:
- db
image: quay.io/keycloak/keycloak:21.0.2
environment:
KC_DB: postgres
KC_DB_ADDR: db
KC_DB_URL_DATABASE: keycloak
KC_DB_URL_HOST: db
KC_DB_URL_PORT: 5432
KC_DB_SCHEMA: public
KC_DB_USERNAME: XXX
KC_DB_PASSWORD: XXX
KEYCLOAK_ADMIN: XXX
KEYCLOAK_ADMIN_PASSWORD: XXX
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth
ports:
- 8080:8080
英文:
For anyone still having this problem:
I discovered that this docker image silently failed to connect to an external Postgres database.
Because there was no error I assumed that the connection was established but I was wrong.
In the new version, new environment parameters was added
The correct parameters for connecting the postgres database to a Keycloak docker image are:
keycloak:
depends_on:
- db
image: quay.io/keycloak/keycloak:21.0.2
environment:
KC_DB: postgres
KC_DB_ADDR: db
KC_DB_URL_DATABASE: keycloak
KC_DB_URL_HOST: db
KC_DB_URL_PORT: 5432
KC_DB_SCHEMA: public
KC_DB_USERNAME: XXX
KC_DB_PASSWORD: XXX
KEYCLOAK_ADMIN: XXX
KEYCLOAK_ADMIN_PASSWORD: XXX
KEYCLOAK_FRONTEND_URL: http://localhost:8080/auth/
volumes:
- ./common/keycloak/disable-theme-cache.cli:/opt/jboss/startup-scripts/disable-theme-cache.cli
command: start-dev --http-relative-path /auth
ports:
- 8080:8080
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论