dasniko / testcontainers-keycloak

A Testcontainer implementation for Keycloak IAM & SSO.
Apache License 2.0
327 stars 50 forks source link

Resteasy exception when using Keycloak Admin Client #82

Closed xgp closed 1 year ago

xgp commented 1 year ago

Describe the bug

I'm using the following test code to create a Keycloak testcontainer and get the admin client:

@Testcontainers
public class OrganizationResourceTest {

  @Container KeycloakContainer server = new KeycloakContainer().withContextPath("/auth/").withProviderClassesFrom("target/classes");

  Keycloak getKeycloak() {
    assertTrue(server.isRunning());
    return server.getKeycloakAdminClient();
  }

  @Test
  public void testCreateDeleteOrg() throws Exception {
    Keycloak keycloak = getKeycloak();
    ...

After the containers start up, I get the following error:

[ERROR] io.phasetwo.service.resources.OrganizationResourceTest.testCreateDeleteOrg  Time elapsed: 69.911 s  <<< ERROR!
java.lang.InstantiationError: org.jboss.resteasy.spi.ResteasyProviderFactory
    at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.getProviderFactory(ResteasyClientBuilder.java:405)
    at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.register(ResteasyClientBuilder.java:559)
    at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.register(ResteasyClientBuilder.java:48)
    at org.keycloak.admin.client.spi.ResteasyClientClassicProvider.newRestEasyClient(ResteasyClientClassicProvider.java:40)
    at org.keycloak.admin.client.Keycloak.newRestEasyClient(Keycloak.java:98)
    at org.keycloak.admin.client.Keycloak.getInstance(Keycloak.java:110)
    at org.keycloak.admin.client.Keycloak.getInstance(Keycloak.java:126)
    at dasniko.testcontainers.keycloak.KeycloakContainer.getKeycloakAdminClient(KeycloakContainer.java:318)
    at io.phasetwo.service.resources.OrganizationResourceTest.getKeycloak(OrganizationResourceTest.java:57)
    at io.phasetwo.service.resources.OrganizationResourceTest.testCreateDeleteOrg(OrganizationResourceTest.java:73)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:55)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:223)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:175)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:139)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)

here are my dependencies

    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.9.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>testcontainers</artifactId>
      <version>1.17.3</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>1.17.3</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.github.dasniko</groupId>
      <artifactId>testcontainers-keycloak</artifactId>
      <version>2.3.0</version>
      <scope>test</scope>
    </dependency>

Any ideas on what is happening?

Version

2.3.0

Expected behavior

The admin client should instantiate without error.

Actual behavior

See exception

How to Reproduce?

run mvn clean install in this branch https://github.com/p2-inc/keycloak-orgs/tree/testcontainers

Relevant log output

see description

Anything else?

No response

xgp commented 1 year ago

I also noticed that it appears to be starting multiple containers. After it starts one, it starts another:

2022-08-09 23:05:51 INFO  ImageNameSubstitutor:55 - Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
2022-08-09 23:05:51 INFO  DockerClientProviderStrategy:363 - Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2022-08-09 23:05:51 WARN  DockerClientProviderStrategy:185 - Unknown DOCKER_HOST scheme ssh, skipping the strategy test...
2022-08-09 23:05:52 INFO  DockerClientProviderStrategy:273 - Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2022-08-09 23:05:52 INFO  DockerClientFactory:183 - Docker host IP address is localhost
2022-08-09 23:05:52 INFO  DockerClientFactory:190 - Connected to docker:
  Server Version: 20.10.12
  API Version: 1.41
  Operating System: Docker Desktop
  Total Memory: 1986 MB
2022-08-09 23:05:52 INFO  3]:376 - Creating container for image: testcontainers/ryuk:0.3.3
2022-08-09 23:05:53 INFO  RegistryAuthLocator:263 - Credential helper/store (docker-credential-desktop) does not have credentials for https://index.docker.io/v1/
2022-08-09 23:05:53 INFO  3]:440 - Container testcontainers/ryuk:0.3.3 is starting: 142891cec38d7a91eafd842f20c4fa8aabaf9a81e1d7cda5864dbbc5729b78e5
2022-08-09 23:05:54 INFO  3]:520 - Container testcontainers/ryuk:0.3.3 started in PT1.29008S
2022-08-09 23:05:54 INFO  RyukResourceReaper:43 - Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
2022-08-09 23:05:54 INFO  DockerClientFactory:220 - Checking the system...
2022-08-09 23:05:54 INFO  DockerClientFactory:241 - βœ”οΈŽ Docker server version should be at least 1.6.0
2022-08-09 23:05:54 INFO  0]:376 - Creating container for image: quay.io/keycloak/keycloak:19.0.0
2022-08-09 23:05:55 INFO  0]:440 - Container quay.io/keycloak/keycloak:19.0.0 is starting: 82987d60a75d61bd20b90c74615fc792f9375117697eddc831a2ddd165ef2417
2022-08-09 23:05:55 INFO  HttpWaitStrategy:235 - /clever_jemison: Waiting for 120 seconds for URL: http://localhost:60043/auth/ (where port 60043 maps to container port 8080)
2022-08-09 23:05:57 INFO  0]:68 - STDOUT: Updating the configuration and installing your custom providers, if any. Please wait.
2022-08-09 23:06:06 INFO  0]:68 - STDOUT: 2022-08-09 21:06:06,565 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: assets (io.phasetwo.service.resource.AssetsResourceProviderFactory) is implementing the internal SPI realm-restapi-extension. This SPI is internal and may change without notice
2022-08-09 23:06:06 INFO  0]:68 - STDOUT: 2022-08-09 21:06:06,570 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: orgs (io.phasetwo.service.resource.OrganizationResourceProviderFactory) is implementing the internal SPI realm-restapi-extension. This SPI is internal and may change without notice
2022-08-09 23:06:06 INFO  0]:68 - STDOUT: 2022-08-09 21:06:06,571 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: teams (io.phasetwo.service.resource.TeamResourceProviderFactory) is implementing the internal SPI realm-restapi-extension. This SPI is internal and may change without notice
2022-08-09 23:06:06 INFO  0]:68 - STDOUT: 2022-08-09 21:06:06,572 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: users (io.phasetwo.service.resource.UserResourceProviderFactory) is implementing the internal SPI realm-restapi-extension. This SPI is internal and may change without notice
2022-08-09 23:06:07 INFO  0]:68 - STDOUT: 2022-08-09 21:06:07,149 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: oidc-organization-role-mapper (io.phasetwo.service.protocol.oidc.mappers.OrganizationRoleMapper) is implementing the internal SPI protocol-mapper. This SPI is internal and may change without notice
2022-08-09 23:06:07 INFO  0]:68 - STDOUT: 2022-08-09 21:06:07,178 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: organization-entity-provider (io.phasetwo.service.model.jpa.entity.OrganizationEntityProviderFactory) is implementing the internal SPI jpa-entity-provider. This SPI is internal and may change without notice
2022-08-09 23:06:07 INFO  0]:68 - STDOUT: 2022-08-09 21:06:07,719 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: ext-portal-link (io.phasetwo.service.auth.PortalLinkAuthenticatorFactory) is implementing the internal SPI authenticator. This SPI is internal and may change without notice
2022-08-09 23:06:07 INFO  0]:68 - STDOUT: 2022-08-09 21:06:07,725 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: invitation-authenticator (io.phasetwo.service.auth.invitation.InvitationAuthenticatorFactory) is implementing the internal SPI authenticator. This SPI is internal and may change without notice
2022-08-09 23:06:08 INFO  0]:68 - STDOUT: 2022-08-09 21:06:08,848 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: invitation-required-action (io.phasetwo.service.auth.invitation.InvitationRequiredActionFactory) is implementing the internal SPI required-action. This SPI is internal and may change without notice
2022-08-09 23:06:09 INFO  0]:68 - STDOUT: 2022-08-09 21:06:09,666 WARN  [org.keycloak.services] (build-68) KC-SERVICES0047: org-portal-link (io.phasetwo.service.auth.action.PortalLinkActionTokenHandlerFactory) is implementing the internal SPI actionTokenHandler. This SPI is internal and may change without notice
2022-08-09 23:06:19 INFO  0]:68 - STDOUT: 2022-08-09 21:06:19,254 INFO  [io.quarkus.deployment.QuarkusAugmentor] (main) Quarkus augmentation completed in 19064ms
2022-08-09 23:06:28 INFO  0]:68 - STDOUT: 2022-08-09 21:06:23,057 INFO  [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: FrontEnd: <request>, Strict HTTPS: false, Path: <request>, Strict BackChannel: false, Admin: <request>, Port: -1, Proxied: false
2022-08-09 23:06:28 INFO  0]:68 - STDOUT: 2022-08-09 21:06:26,403 INFO  [org.keycloak.common.crypto.CryptoIntegration] (main) Detected crypto provider: org.keycloak.crypto.def.DefaultCryptoProvider
2022-08-09 23:06:32 INFO  0]:68 - STDOUT: 2022-08-09 21:06:32,421 WARN  [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
2022-08-09 23:06:32 INFO  0]:68 - STDOUT: 2022-08-09 21:06:32,561 WARN  [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
2022-08-09 23:06:32 INFO  0]:68 - STDOUT: 2022-08-09 21:06:32,621 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
2022-08-09 23:06:33 INFO  0]:68 - STDOUT: 2022-08-09 21:06:33,380 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000128: Infinispan version: Infinispan 'Triskaidekaphobia' 13.0.9.Final
2022-08-09 23:06:34 INFO  0]:68 - STDOUT: 2022-08-09 21:06:34,389 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_329962, Site name: null
2022-08-09 23:06:38 INFO  0]:68 - STDOUT: 2022-08-09 21:06:38,298 INFO  [org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-master.xml
2022-08-09 23:06:45 INFO  0]:68 - STDOUT: 2022-08-09 21:06:45,756 INFO  [org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-phasetwo-master.xml
2022-08-09 23:06:46 INFO  0]:68 - STDOUT: 2022-08-09 21:06:46,617 INFO  [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
2022-08-09 23:06:48 INFO  0]:68 - STDOUT: 2022-08-09 21:06:48,635 INFO  [io.phasetwo.service.resource.OrganizationResourceProviderFactory] (main) RealmPostCreateEvent
2022-08-09 23:06:51 INFO  0]:68 - STDOUT: 2022-08-09 21:06:51,420 INFO  [io.phasetwo.service.resource.OrganizationResourceProviderFactory] (main) PostMigrationEvent
2022-08-09 23:06:52 INFO  0]:68 - STDOUT: 2022-08-09 21:06:52,154 INFO  [io.quarkus] (main) Keycloak 19.0.0 on JVM (powered by Quarkus 2.7.6.Final) started in 32.261s. Listening on: http://0.0.0.0:8080
2022-08-09 23:06:52 INFO  0]:68 - STDOUT: 2022-08-09 21:06:52,155 INFO  [io.quarkus] (main) Profile dev activated.
2022-08-09 23:06:52 INFO  0]:68 - STDOUT: 2022-08-09 21:06:52,156 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, smallrye-metrics, vault, vertx]
2022-08-09 23:06:52 INFO  0]:68 - STDOUT: 2022-08-09 21:06:52,974 INFO  [org.keycloak.services] (main) KC-SERVICES0009: Added user 'admin' to realm 'master'
2022-08-09 23:06:52 INFO  0]:68 - STDOUT: 2022-08-09 21:06:52,992 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
2022-08-09 23:06:54 INFO  0]:520 - Container quay.io/keycloak/keycloak:19.0.0 started in PT59.85402S
2022-08-09 23:06:55 INFO  0]:376 - Creating container for image: quay.io/keycloak/keycloak:19.0.0
2022-08-09 23:06:55 INFO  0]:440 - Container quay.io/keycloak/keycloak:19.0.0 is starting: 8dfedfc92856a053e47500c36a35d5bba5b429b43f90bf1de53756c1771f6f38
2022-08-09 23:06:56 INFO  HttpWaitStrategy:235 - /nervous_ritchie: Waiting for 120 seconds for URL: http://localhost:60165/auth/ (where port 60165 maps to container port 8080)
2022-08-09 23:06:57 INFO  0]:68 - STDOUT: Updating the configuration and installing your custom providers, if any. Please wait.
...

Is it stuck in some kind of loop?

dasniko commented 1 year ago

Hi @xgp this is one of the issues from the category "having fun with resteasy dependencies", or, as I wrote one time in a commit message: "fighting the resteasy dependency war" πŸ˜”

The keycloak-services package (from your regular dependencies, not test scope) has a transitive dependency to resteasy version 4.7.x, what is aligned to the resteasy runtime version in keycloak. That's good! Unfortunately, the keycloak-admin-client has a dependency to resteasy version 3.x - which collides with the 4.7.x as they are not compatible.

A possible solution could(!) be to exclude the 3.x dependencies and to include all needed/proper 4.7.x dependencies and to create an instance of the admin client by yourself, by providing a proper resteasy client. This might work, might not work. All this resteasy dependency thing in Keycloak is such a crap... πŸ€·β€β™‚οΈ

dasniko commented 1 year ago

Your second "issue", starting multiple containers, is not related to the Keycloak Testcontainers. It's the way, the Testcontainers work:

You declare your container instance as a class member. In this way, for each test, a new container will be started. If you declare your container as a static class member, then only one container is started and all tests will use this one container. Depending on what you need in your tests (clean and isolated environments or not), the one or the other approach might be the proper one for your. I prefer to start only one container for all of my tests, in most cases.

xgp commented 1 year ago

fighting the resteasy dependency war

Thanks @dasniko. I see now how to get the dependencies right so that they resolve properly for both in-container and test resteasy needs.

One additional question I am wrestling with is getting library dependencies loaded. I have the following setup:

  static final List<File> dependencies = Maven.resolver()
                                        .loadPomFromFile("./pom.xml")
                                        .resolve("org.keycloak:keycloak-admin-client")
                                        .withoutTransitivity().asList(File.class);

  @Container static final KeycloakContainer server = new KeycloakContainer("quay.io/keycloak/keycloak:19.0.1").withContextPath("/auth/").withProviderClassesFrom("target/classes").withProviderLibsFrom(dependencies);

I see a bunch of attempts to modify the QuarkusClassLoader, but ultimately appears to fail because it can't create the filesystem in the container for the library dependencies:

...
2022-08-10 20:19:53 INFO  1]:75 - STDERR: 2022-08-10 18:19:50,908 DEBUG [io.quarkus.bootstrap.classloading.QuarkusClassLoader] (main) Adding elements io.quarkus.bootstrap.classloading.PathTreeClassPathElement@16423501 to QuarkusClassLoader Deployment Class Loader: PROD
2022-08-10 20:19:53 INFO  1]:75 - STDERR:
2022-08-10 20:19:53 INFO  1]:75 - STDERR: 2022-08-10 18:19:50,909 DEBUG [io.quarkus.bootstrap.classloading.QuarkusClassLoader] (main) Adding elements io.quarkus.bootstrap.classloading.PathTreeClassPathElement@4efcf8a to QuarkusClassLoader Deployment Class Loader: PROD
2022-08-10 20:19:53 INFO  1]:75 - STDERR:
2022-08-10 20:19:53 INFO  1]:75 - STDERR: ERROR: Failed to run 'build' command.
2022-08-10 20:19:53 INFO  1]:75 - STDERR: ERROR: java.io.IOException: Failed to create a new filesystem for /opt/keycloak/lib/../providers/keycloak-admin-client-19.0.1.jar
2022-08-10 20:19:53 INFO  1]:75 - STDERR: ERROR: Failed to create a new filesystem for /opt/keycloak/lib/../providers/keycloak-admin-client-19.0.1.jar
2022-08-10 20:19:53 INFO  1]:75 - STDERR: ERROR: /opt/keycloak/lib/../providers/keycloak-admin-client-19.0.1.jar
2022-08-10 20:19:53 INFO  1]:75 - STDERR: For more details run the same command passing the '--verbose' option. Also you can use '--help' to see the details about the usage of the particular command.
2022-08-10 20:21:45 ERROR 1]:529 - Could not start container
java.lang.IllegalStateException: Container exited with code 1
    at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:514)
    at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:344)
    at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
    at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:334)
    at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:322)
    at org.testcontainers.junit.jupiter.TestcontainersExtension$StoreAdapter.start(TestcontainersExtension.java:242)
    at org.testcontainers.junit.jupiter.TestcontainersExtension$StoreAdapter.access$200(TestcontainersExtension.java:229)
    at org.testcontainers.junit.jupiter.TestcontainersExtension.lambda$null$1(TestcontainersExtension.java:56)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$getOrComputeIfAbsent$4(ExtensionValuesStore.java:86)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.computeValue(ExtensionValuesStore.java:223)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.get(ExtensionValuesStore.java:211)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.evaluate(ExtensionValuesStore.java:191)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.access$100(ExtensionValuesStore.java:171)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.getOrComputeIfAbsent(ExtensionValuesStore.java:89)
    at org.junit.jupiter.engine.execution.NamespaceAwareStore.getOrComputeIfAbsent(NamespaceAwareStore.java:53)
    at org.testcontainers.junit.jupiter.TestcontainersExtension.lambda$beforeAll$2(TestcontainersExtension.java:56)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.testcontainers.junit.jupiter.TestcontainersExtension.beforeAll(TestcontainersExtension.java:55)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:395)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:395)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:211)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:84)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:55)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:223)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:175)
    at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:139)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
    at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)

I followed your example here. Can you see something I'm obviously doing wrong?

xgp commented 1 year ago

Follow up on the above observation, I tried using the testcontainers method directly. It appears that withCopyFileToContainer isn't working as expected. The following code:

  @Container static final KeycloakContainer server = 
    new KeycloakContainer("quay.io/keycloak/keycloak:19.0.1")
      .withCopyFileToContainer(MountableFile.forHostPath("/Users/garth/.m2/repository/org/keycloak/keycloak-admin-client/19.0.1/keycloak-admin-client-19.0.1.jar"), "/opt/keycloak/providers/keycloak-admin-client-19.0.1.jar");

gives this error

ERROR: java.io.IOException: Failed to create a new filesystem for /opt/keycloak/lib/../providers/keycloak-admin-client-19.0.1.jar

I'm not sure how/why it's altering the path.

dasniko commented 1 year ago

I can't really reproduce this behavior...

But I see a coincidence with a similar error message when dealing with Docker containers on my machine, when there is e.g. not enough memory available to the Docker process itself, or similar. Did you try to give your Docker more memory/cpu?

xgp commented 1 year ago

I’ll try it with more resources for Docker and report back. Thanks again.

On Mon, Aug 15, 2022, at 5:18 AM, Niko KΓΆbler wrote:

I can't really reproduce this behavior...

But I see a coincidence with a similar error message when dealing with Docker containers on my machine, when there is e.g. not enough memory available to the Docker process itself, or similar. Did you try to give your Docker more memory/cpu?

β€” Reply to this email directly, view it on GitHub https://github.com/dasniko/testcontainers-keycloak/issues/82#issuecomment-1214948477, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB3UHLBGTI554ZUEWDZOFLVZIYTBANCNFSM56CEPPPQ. You are receiving this because you were mentioned.Message ID: @.***>

xgp commented 1 year ago

@dasniko I'm still struggling with the same problem. I made a simple repo where you can reproduce the problem. https://github.com/xgp/testcontainers-keycloak-test

I use the provider classes and libs methods like this:

  static final List<File> dependencies = Maven.resolver()
                                         .loadPomFromFile("./pom.xml")
                                         .resolve("org.keycloak:keycloak-admin-client")
                                         .withoutTransitivity().asList(File.class);

  @Container static final KeycloakContainer server = new KeycloakContainer("quay.io/keycloak/keycloak:20.0.1").withContextPath("/auth/").withProviderClassesFrom("target/classes").withProviderLibsFrom(dependencies);

And I still get the error:

ERROR: java.io.IOException: Failed to create a new filesystem for /opt/keycloak/lib/../providers/keycloak-admin-client-20.0.1.jar

2 questions:

  1. if you run mvn clean install on that repo, do you see the same error?
  2. do you see anything obvious I'm doing wrong in the code or pom?

Thanks again.

xgp commented 1 year ago

Also, per our previous messages about Docker resources, I don't think that's a problem, as I've given it 4 vcpus and 8GB of ram and nothing else is running. I have no trouble running multiple keycloak instances in docker.

dasniko commented 1 year ago

Everything is fine over here...

My log output for reference:

➜  testcontainers-keycloak-test git:(main) βœ— mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< test:testcontainers-keycloak-test >------------------
[INFO] Building testcontainers-keycloak-test 0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ testcontainers-keycloak-test ---
[INFO] Deleting /Users/niko/dev/tmp/testcontainers-keycloak-test/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ testcontainers-keycloak-test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/niko/dev/tmp/testcontainers-keycloak-test/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:compile (default-compile) @ testcontainers-keycloak-test ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/niko/dev/tmp/testcontainers-keycloak-test/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ testcontainers-keycloak-test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:testCompile (default-testCompile) @ testcontainers-keycloak-test ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/niko/dev/tmp/testcontainers-keycloak-test/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:3.0.0-M7:test (default-test) @ testcontainers-keycloak-test ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running test.FooTest
[main] INFO org.testcontainers.utility.ImageNameSubstitutor - Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
[main] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy - Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
[main] WARN org.testcontainers.dockerclient.DockerClientProviderStrategy - DOCKER_HOST tcp://127.0.0.1:49893 is not listening
[main] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy - Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
[main] INFO org.testcontainers.DockerClientFactory - Docker host IP address is localhost
[main] INFO org.testcontainers.DockerClientFactory - Connected to docker:
  Server Version: 20.10.20
  API Version: 1.41
  Operating System: Docker Desktop
  Total Memory: 11979 MB
[main] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - Creating container for image: quay.io/keycloak/keycloak:20.0.1
[main] INFO org.testcontainers.utility.RegistryAuthLocator - Credential helper/store (docker-credential-desktop) does not have credentials for quay.io
[main] INFO 🐳 [testcontainers/ryuk:0.3.3] - Creating container for image: testcontainers/ryuk:0.3.3
[main] INFO 🐳 [testcontainers/ryuk:0.3.3] - Container testcontainers/ryuk:0.3.3 is starting: 8d2e9c87fbc21acbc06970b2ba13f375a729e5701369a2d19ea2fc4339ef3c20
[main] INFO 🐳 [testcontainers/ryuk:0.3.3] - Container testcontainers/ryuk:0.3.3 started in PT0.423393S
[main] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - Container quay.io/keycloak/keycloak:20.0.1 is starting: 48d252edc7d8e05ffa1cda1d7b092e260f7090155f4a94d9ff5b336795066824
[main] INFO org.testcontainers.containers.wait.strategy.HttpWaitStrategy - /stoic_haslett: Waiting for 120 seconds for URL: http://localhost:56456/auth/ (where port 56456 maps to container port 8080)
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: Updating the configuration and installing your custom providers, if any. Please wait.
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:13,575 INFO  [io.quarkus.deployment.QuarkusAugmentor] (main) Quarkus augmentation completed in 5157ms
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:14,904 INFO  [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: <unset>, Hostname: <request>, Strict HTTPS: false, Path: <request>, Strict BackChannel: false, Admin URL: <unset>, Admin: <request>, Port: -1, Proxied: false
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:15,838 WARN  [io.quarkus.agroal.runtime.DataSources] (main) Datasource <default> enables XA but transaction recovery is not enabled. Please enable transaction recovery by setting quarkus.transaction-manager.enable-recovery=true, otherwise data may be lost if the application is terminated abruptly
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:16,575 WARN  [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:16,581 WARN  [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:16,600 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:16,854 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000128: Infinispan version: Infinispan 'Triskaidekaphobia' 13.0.10.Final
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:17,891 INFO  [org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-master.xml
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:19,213 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_541970, Site name: null
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:19,279 INFO  [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:19,285 INFO  [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:20,673 INFO  [io.quarkus] (main) Keycloak 20.0.1 on JVM (powered by Quarkus 2.13.3.Final) started in 6.953s. Listening on: http://0.0.0.0:8080
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:20,673 INFO  [io.quarkus] (main) Profile dev activated.
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:20,673 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, smallrye-metrics, vault, vertx]
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:20,984 INFO  [org.keycloak.services] (main) KC-SERVICES0009: Added user 'admin' to realm 'master'
[docker-java-stream--943534655] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - STDOUT: 2022-11-15 14:19:20,987 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
[main] INFO 🐳 [quay.io/keycloak/keycloak:20.0.1] - Container quay.io/keycloak/keycloak:20.0.1 started in PT15.259029S
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 17.251 s - in test.FooTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) @ testcontainers-keycloak-test ---
[INFO] Building jar: /Users/niko/dev/tmp/testcontainers-keycloak-test/target/testcontainers-keycloak-test-0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  20.053 s
[INFO] Finished at: 2022-11-15T15:19:22+01:00
[INFO] ------------------------------------------------------------------------
dasniko commented 1 year ago

I sometimes encounter this error message Failed to create a new filesystem for... if there are other stopped/dangling Keycloak containers. Don't know exactly why, but removing them makes it work again. πŸ€·β€β™‚οΈ

xgp commented 1 year ago

🀦 I'm just going to do a complete docker reinstall. At least I know it's something wrong with my setup.

dasniko commented 1 year ago

Closing this for now.