# A real issuer, in one command. # # docker compose -f docker/compose.yaml up -d # ./scripts/run-rs.sh keycloak,roles # ./scripts/keycloak-demo.sh # # Notes that matter for a resource server: # # * KC_HOSTNAME fixes the issuer string. Keycloak derives `iss` from the request host # unless you pin it, so a token fetched via localhost and a token fetched via a # container name carry DIFFERENT issuers and one of them will fail JwtIssuerValidator. # Pinning it is the single most common fix for "it works from curl but not from the app". # # * start-dev keeps everything in an in-memory H2 database. Every restart is a fresh realm # and, importantly for this repository, a fresh signing key. # # * The realm is imported at boot from realm-demo.json, so the demo users, roles and the # audience mapper exist without any admin-console clicking. services: keycloak: image: quay.io/keycloak/keycloak:26.7.2 container_name: jwt-demo-keycloak command: ["start-dev", "--import-realm"] environment: KC_BOOTSTRAP_ADMIN_USERNAME: admin KC_BOOTSTRAP_ADMIN_PASSWORD: admin KC_HOSTNAME: http://localhost:8080 KC_HOSTNAME_STRICT: "false" KC_HTTP_ENABLED: "true" KC_HEALTH_ENABLED: "true" ports: - "8080:8080" volumes: - ./realm-demo.json:/opt/keycloak/data/import/realm-demo.json:ro