Attempt 2 - Using Keycloak 19.0.3 and configure the built-in Infinispan cache to use database persistence (Ideas taken from - jGroups/Infinispan Bedevilling: No DB Table Created (Unable to persist Infinispan internal caches as no global state enabled) - Miscellanaeous - Keycloak)
Result - Keycloak container starts without any errors, the JGROUPSPING table is created in the keycloak PostgreSQL database with 1 row (cluster_name - “ISPN”) but again the user session is lost after restarting the Keycloak container
- docker-compose.yml
keycloak:
container_name: ${APP_NAME}_keycloak
image: Quay
restart: “no” # unless-stoppedvolumes: - ./scripts/keycloak-import:opt/keycloak/imports - ./keycloak/conf/cache-ispn.xml:opt/keycloak/conf/cache-ispn.xml command: >- start-dev --cache=ispn --cache-config-file=cache-ispn.xml --db=postgres --db-url-host=db --db-url-database=keycloak --db-username=$DB_USERNAME --db-password=$DB_PASSWORD --proxy=edge --http-relative-path=/auth/ ports: - 8080:8080 depends_on: - dbvolumes:
my_volume:
external: true
certificates:
- ./keyclock/conf/cache-ispn.xml
<?xml version="1.0" encoding="UTF-8"?><jgroups> <stack name="jdbc-ping-tcp" extends="tcp"> <JDBC_PING connection_driver="org.postgresql.Driver" connection_url="jdbc:postgresql://127.0.0.1:5438/keycloak" connection_username="{UserName}" connection_password="{Password}" initialize_sql="CREATE TABLE IF NOT EXISTS JGROUPSPING (own_addr varchar(200) NOT NULL, cluster_name varchar(200) NOT NULL, ping_data BYTEA, constraint PK_JGROUPSPING PRIMARY KEY (own_addr, cluster_name));" info_writer_sleep_time="500" remove_all_data_on_view_change="true" stack.combine="REPLACE" stack.position="MPING" /> </stack> </jgroups> <cache-container name="keycloak"> <transport lock-timeout="60000" stack="jdbc-ping-tcp"/> <local-cache name="realms"> <encoding> <key media-type="application/x-java-object"/> <value media-type="application/x-java-object"/> </encoding> <memory max-count="10000"/> </local-cache> <local-cache name="users"> <encoding> <key media-type="application/x-java-object"/> <value media-type="application/x-java-object"/> </encoding> <memory max-count="10000"/> </local-cache> <distributed-cache name="sessions" owners="2"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> <distributed-cache name="authenticationSessions" owners="2"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> <distributed-cache name="offlineSessions" owners="2"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> <distributed-cache name="clientSessions" owners="2"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> <distributed-cache name="offlineClientSessions" owners="2"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> <distributed-cache name="loginFailures" owners="2"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> <local-cache name="authorization"> <encoding> <key media-type="application/x-java-object"/> <value media-type="application/x-java-object"/> </encoding> <memory max-count="10000"/> </local-cache> <replicated-cache name="work"> <expiration lifespan="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </replicated-cache> <local-cache name="keys"> <encoding> <key media-type="application/x-java-object"/> <value media-type="application/x-java-object"/> </encoding> <expiration max-idle="3600000"/> <memory max-count="1000"/> </local-cache> <distributed-cache name="actionTokens" owners="2"> <encoding> <key media-type="application/x-java-object"/> <value media-type="application/x-java-object"/> </encoding> <expiration max-idle="-1" lifespan="-1" interval="300000"/> <memory max-count="-1"/> <persistence> <file-store preload="true" fetch-state="true"/> </persistence> </distributed-cache> </cache-container>