keycloak: Keycloak Export only accept H2 datase-URL (Datasource: URL format error; must be jdbc:h2 ... but is jdbc:mariadb: ...)

Before reporting an issue

  • I have searched existing issues
  • I have reproduced the issue with the latest release

Area

dist/quarkus

Describe the bug

I like to export Keycloak-data from a MariaDB database, but it’s not possible.

The source I use is: https://www.keycloak.org/server/importExport

The export command export only accepts a H2 database-URL, even I’ve created a build with proper database vendor. I’ve created a new build before execute the export: build --db=mariadb

There is an error displayed if I try to export the Keycloak-data from the MariaDB database.

The error is:

Datasource '<default>': URL format error; must be "jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]" but is "jdbc:mariadb://db.my-domain.de:3306/keycloak"

Version

20.0.1

Expected behavior

The expected behavior is , that the export command accept a MariaDB database-URL like jdbc:mariadb:....

Actual behavior

The actual behavior is , that the export command only accept a H2 database-URL like jdbc:h2:... even if I execute build --db=mariadb before.

Also, the show-config commands shows that kc.db = mariadb (KcEnvVarConfigSource) it isn’t.

How to Reproduce?

version: '3.9'

services:
  keycloak-export:
      container_name: keycloak-export
      image: quay.io/keycloak/keycloak:latest
      environment:
        KC_HOSTNAME: login.my-domain.com
        KC_HOSTNAME_STRICT_HTTPS: true 
        KC_HTTP_ENABLED: false
        KC_PROXY: edge
        KC_DB: mariadb
        KC_DB_URL_HOST: db.my-domain.com
        KC_DB_URL_DATABASE: keycloak
        KC_DB_URL_PORT: 3306
        KC_DB_USERNAME: ***
        KC_DB_PASSWORD: ***
        KC_HTTPS_KEY_STORE_FILE: /keystore.p12
        KC_HTTPS_KEY_STORE_PASSWORD: ***
      command:
        - export --dir /export_data
      volumes:
        - ./keystore.p12:/keystore.p12
        - ./export_data:/export_data
      restart: "no"

Anything else?

In production mode, the Keycloak-Server connects to MariaDB-Database-Server based on this Docker Compose file:

version: '3.9'

services:
  keycloak:
      container_name: keycloak
      image: quay.io/keycloak/keycloak:latest
      environment:
        KC_HOSTNAME: login.my-domain.de
        KC_HOSTNAME_STRICT_HTTPS: true 
        KC_HTTP_ENABLED: false
        KC_PROXY: edge
        KC_DB: mariadb
        KC_DB_URL_HOST: db.my-domain.de
        KC_DB_URL_DATABASE: keycloak
        KC_DB_URL_PORT: 3306
        KC_DB_USERNAME: ***
        KC_DB_PASSWORD: ***
        KC_HTTPS_KEY_STORE_FILE: /keystore.p12
        KC_HTTPS_KEY_STORE_PASSWORD: ***
        KEYCLOAK_ADMIN: ***
        KEYCLOAK_ADMIN_PASSWORD: ***
        KC_TRANSACTION_XA_ENABLED: true
        KC_HEALTH_ENABLED: true
        KC_METRICS_ENABLED: true
      command:
        - start
      ports:
        - 8080:8080
      volumes:
        - ./keystore.p12:/keystore.p12
      restart: always

The connection is successfully and Keycloak-data is stored in MariaDB database.

Stackoverflow discussion

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 2
  • Comments: 15 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I just got the same issue, it was solved by removing the --optimized from the start command.

I preferred not to build an image, so I overwrote the entrypoint and ran both the build and the import/export.

 keycloak:
    image: quay.io/keycloak/keycloak:20.0 
    depends_on:
      - postgres
    env_file:
      - .env
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://${KEYCLOAK_DB_ADDR}/${KEYCLOAK_DB_NAME}?user=${KEYCLOAK_DB_USER}&password=${KEYCLOAK_DB_PASS}
      KEYCLOAK_ADMIN: ${KEYCLOAK_USER}
      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_PASSWORD}
    volumes:
      - ${CONFIG_PATH_HOST}/keycloak/initial-config:/opt/jboss/keycloak/config
    command: start-dev --import-realm 
      

keycloak-importer:
      image: quay.io/keycloak/keycloak:20.0 
      depends_on:
        - postgres
      env_file:
        - .env
      environment:
        KC_DB: postgres
        KC_DB_URL: jdbc:postgresql://${KEYCLOAK_DB_ADDR}/${KEYCLOAK_DB_NAME}?user=${KEYCLOAK_DB_USER}&password=${KEYCLOAK_DB_PASS}      
      volumes:
        - ${CONFIG_PATH_HOST}/keycloak/initial-config:/opt/jboss/keycloak/config
      entrypoint: sh
      command: -c "/opt/keycloak/bin/kc.sh build && sh /opt/keycloak/bin/kc.sh import --dir /opt/jboss/keycloak/config"

  keycloak-exporter:
      image: quay.io/keycloak/keycloak:20.0 
      depends_on:
        - postgres
      env_file:
        - .env
      environment:
        KC_DB: postgres
        KC_DB_URL: jdbc:postgresql://${KEYCLOAK_DB_ADDR}/${KEYCLOAK_DB_NAME}?user=${KEYCLOAK_DB_USER}&password=${KEYCLOAK_DB_PASS}      
      volumes:
        - ${CONFIG_PATH_HOST}/keycloak/exports:/opt/jboss/keycloak/exports
      entrypoint: sh
      command: -c "/opt/keycloak/bin/kc.sh build && sh /opt/keycloak/bin/kc.sh export --dir /opt/jboss/keycloak/exports"

I think it would be convenient to enable a mechanism that allows import/export as expected after reading the official documentation. In the meantime, I think it would be necessary to add information about it in the documentation. At least, I have not found any information about it.

@OtenMoten I encountered the same issue as you reported. You could use the following workaround:

  1. Create a Dockerfile that builds keycloak before running the kc.sh command, e.g.
FROM quay.io/keycloak/keycloak:latest as builder

# Configure a database vendor
ENV KC_DB=postgres

WORKDIR /opt/keycloak
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/

ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

(slim version of the example on https://www.keycloak.org/server/containers)

  1. Use this Dockerfile in your docker-compose.yml (replace image: quay.io/keycloak/keycloak:latest with build: ./PATH_TO_DIRECTORY_WHICH_CONTAINS_DOCKERFILE

This solved the issue for me, however, it is just an ugly workaround - the problem should still be fixed off-course.

I just got the same issue, it was solved by removing the --optimized from the start command.

I know what you are talking about, I had the same issue with start --optimized but in this case I write about export.

As you can see in the Docker Compose file there is no --optimized just start and export has no --optimized.

@ggalejandro - thank you for providing this example when running this with containers. I now see that it is extra complicated when running the standard container. I’ve been running it with the ZIP distribution and wasn’t aware of this.

@ahus1 Thanks for your comment, and sorry guys for the late response. This kind of issue was already discussed in the past. See #14228.

We need to discuss the correct approach for import/export. But I’m leaning towards supporting “auto-build” functionality for export with assessing backward compatibility; support both approaches.

@mabartos / @vmuzikar - it would be great if export would have the auto-build option.