skip to Main Content

I have an Spring boot java application that uses Keycloak for authentication and authorization.
I have created my realm and its users and roles. I want to dockerize the application using docker compose. So I have crated a docker image of my java application.
But when I want to create a Keycloak instance(pulling Keyckloak image from dockerhub), I will lose my persisted realms, users and roles which I had created before because it creates a new Keycloak from the pulled docker image. How to keep this data persisted, every time I run the application using docker compose?
Actually I need the Keycloak data(realms, users and roles) to be initialized automatically whenever I run docker compose.

Update:

Let me make the problem clearer.

I want to put the codes on Github and when somebody gets and runs it (thorough docker compose); by predefined keycloak users and passwords, use the application. The problem is that, when somebody each time runs the code by docker compose, there is no realm, users and roles because the Keycloak image is pulled and runs without any data(realms, user and so on). Actually I do not want the users who run the application, define the Keycloak data(realm, user and so on). I want this data already be exist on each application running so the users can login to my application and use it.

application.yml:

spring:
  application:
    name: my-client
  security:
    oauth2:
      client:
        registration:
          myclientapp:
            client-id: my-client-app
            client-secret: secrectKey12345
            scope: openid, profile, roles
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8085/login/oauth2/code/myclientapp
        provider:
          myclientapp:
            authorization-uri: http://localhost:8080/realms/myclientapp/protocol/openid-connect/auth
            token-uri: http://localhost:8080/realms/myclientapp/protocol/openid-connect/token
            jwk-set-uri: http://localhost:8080/realms/myclientapp/protocol/openid-connect/certs
            user-info-uri: http://localhost:8080/realms/myclientapp/protocol/openid-connect/userinfo
            user-name-attribute: preferred_username

pox.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.my-client</groupId>
    <artifactId>client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>client</name>
    <description>Demo project for Spring Client</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Thanks a lot.

2

Answers


  1. Short answer

    Export your Keycloak realm and users and add it to the container /opt/keycloak/data/import/ folder.

    Step by step

    Once your realm clients and users are configured with Keycloak admin UI, in Docker desktop:

    • go to your Keycloak container Exec tab to run:
    cd /opt/keycloak/bin/
    sh ./kc.sh export --dir /tmp/keycloak/ --users realm_file
    
    • go to Files tab and grab the export file for the realm you want to restore in /tmp/keycloak/ (here after I store it in the ./keycloak/import/ directory, relative to the Docker compose file, but could have chosen ./keycloak/data/import/ to keep the same directory structure as Keycloak install in the container)
    • edit your compose file to add a volume to mount at /opt/keycloak/data/import/ the directory where you saved the file exported from Keycloak. In my case:
        volumes:
          - ./keycloak/import/:/opt/keycloak/data/import/
    

    Sample complete projects doing that:

    Login or Signup to reply.
  2. I think, if we configure our database, they should be persisted.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search