Fail to create container image: No enum constant org.keycloak.common.Profile.ProfileValue.TOKEN-EXCHANGE

Are the instructions at Keycloak - Server - Running Keycloak in a container accurate? With the example Dockerfile, the kc.sh build results in:

[1/2] STEP 5/5: RUN /opt/keycloak/bin/kc.sh build
Updating the configuration and installing your custom providers, if any. Please wait.
ERROR: Failed to run 'build' command.
ERROR: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step org.keycloak.quarkus.deployment.KeycloakProcessor#configureProviders threw an exception: java.lang.IllegalArgumentException: No enum constant org.keycloak.common.Profile.ProfileValue.TOKEN-EXCHANGE

I’m not sure what that error is trying to tell me; I’d appreciate any pointers. Thanks!

I removed the line:

ENV KC_FEATURES=token-exchange

That got me further but it seems like there’s something that tries to log in to the database with the user sa after that.

I think the current docker setup is broken.

I think the current docker setup is broken.

Agreed. If I remove the ENV KC_FEATURES=token-exchange it actually builds just fine for me, but at startup appears to ignore the KC_* environment variables that are meant to configure database access.

I have a feeling that locking it to 17.0.0 rather than choosing latest might work.

I got it running on “bare metal” so I haven’t got the time to play more with the docker side of things today.

“17.0.0” is not one of the available tags (from the quay.io/keycloak/keycloak-x repository). The most recent that is not “latest” is 16.1.1.

I was able to get things running with the following Dockerfile:

FROM quay.io/keycloak/keycloak-x:latest as builder

RUN /opt/keycloak/bin/kc.sh build \
	--db=postgres \
	--metrics-enabled=true \
	--features-token_exchange=enabled

FROM quay.io/keycloak/keycloak-x:latest
COPY --from=builder /opt/keycloak/lib/quarkus/ /opt/keycloak/lib/quarkus/
WORKDIR /opt/keycloak

# for demonstration purposes only, please make sure to use proper
# certificates in production instead
RUN keytool \
  -genkeypair \
  -storepass password \
  -storetype PKCS12 \
  -keyalg RSA \
  -keysize 2048 \
  -dname "CN=server" \
  -alias server \
  -ext "SAN:c=DNS:localhost,IP:127.0.0.1" \
  -keystore conf/server.keystore

ENV KEYCLOAK_ADMIN=admin
ENV KEYCLOAK_ADMIN_PASSWORD=change_me
ENV KC_HOSTNAME=localhost:8443
ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]

And the following invocation in my docker-compose.yaml:

  keycloak:
    image: keycloak
    ports:
      - "8080:8080"
      - "8443:8443"
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: secret
      KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
    command:
      - --http-enabled=true
      - --db-username=${POSTGRES_USER}
      - --db-password=${POSTGRES_PASSWORD}

Of particular note, the KC_DB_USERNAME and KC_DB_PASSWORD environment variables don’t appear to work, which is why I had to provide them on the command line instead.

keycloak-x was just the preview versions, it’s now regular quay.io/keycloak/keycloak.
Legacy version have the -legacy to the version tag, e.g. quay.io/keycloak/keycloak:17.0.0-legacy.

This is also mentioned in the blog post and migration guide!

The forum just ate my post, so I’ll try again.

I was able to get things running with the latest image using the following Dockerfile:

FROM quay.io/keycloak/keycloak-x:latest as builder

RUN /opt/keycloak/bin/kc.sh build \
	--db=postgres \
	--metrics-enabled=true \
	--features-token_exchange=enabled

FROM quay.io/keycloak/keycloak-x:latest
COPY --from=builder /opt/keycloak/lib/quarkus/ /opt/keycloak/lib/quarkus/
WORKDIR /opt/keycloak

# for demonstration purposes only, please make sure to use proper
# certificates in production instead
RUN keytool \
  -genkeypair \
  -storepass password \
  -storetype PKCS12 \
  -keyalg RSA \
  -keysize 2048 \
  -dname "CN=server" \
  -alias server \
  -ext "SAN:c=DNS:localhost,IP:127.0.0.1" \
  -keystore conf/server.keystore

ENV KEYCLOAK_ADMIN=admin
ENV KEYCLOAK_ADMIN_PASSWORD=change_me
ENV KC_HOSTNAME=localhost:8443

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

Here, I’ve dropped use of the KC_* environment variables for configuration and just provided equivalent command line arguments.

I’m using the following invocation in my docker-compose.yaml:

  keycloak:
    image: keycloak
    ports:
      - "8080:8080"
      - "8443:8443"
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: secret
      KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
      KC_HOSTNAME: localhost:8443
    command:
      - --http-enabled=true
      - --db-username=${POSTGRES_USER}
      - --db-password=${POSTGRES_PASSWORD}

Note that while KC_DB_URL appears to work just fine, KC_DB_USERNAME and KC_DB_PASSWORD do not, so those had to be provided on the command line rather than as environment variables.

What blog post? What migration guide? I’m following the container guide, which seems to have some misinformation in it.

Using the quay.io/keycloak/keycloak repository, it looks like I’ll need to start from scratch because kc.sh appears to have changed completely. Maybe the “migration guide” addresses this? I’ll see if I can find it.

The blog post for the 17 release:

https://www.keycloak.org/2022/02/keycloak-1700-released

The current container guide seems to have a type as it uses the keycloak-x image.
Trying to find the source and doing a PR for fixing this…

UPDATE: It’s already fixed in the sources of the guide, but not yet published…

Using quay.io/keycloak/keycloak, things seems to work a little better. The KC_* environment variables appear to work as described, so I can use this Dockerfile:

FROM quay.io/keycloak/keycloak:17.0.0 as builder

ENV KC_DB=postgres
ENV KC_METRICS_ENABLED=true
ENV KC_FEATURES=token-exchange
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:17.0.0
COPY --from=builder /opt/keycloak/lib/quarkus/ /opt/keycloak/lib/quarkus/
WORKDIR /opt/keycloak

# for demonstration purposes only, please make sure to use proper
# certificates in production instead
RUN keytool \
  -genkeypair \
  -storepass password \
  -storetype PKCS12 \
  -keyalg RSA \
  -keysize 2048 \
  -dname "CN=server" \
  -alias server \
  -ext "SAN:c=DNS:localhost,IP:127.0.0.1" \
  -keystore conf/server.keystore

ENV KEYCLOAK_ADMIN=admin
ENV KEYCLOAK_ADMIN_PASSWORD=change_me
ENV KC_HOSTNAME=localhost:8443

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

And this invocation:

  keycloak:
    image: keycloak:17.0.0
    ports:
      - "8080:8080"
      - "8443:8443"
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
      KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
      KC_DB_USERNAME: ${POSTGRES_USER}
      KC_DB_PASSWORD: ${POSTGRES_PASSWORD}