Skip to content

Architecture

How the pieces fit together, and why the image is built the way it is.

What's in the image

The repo produces a single self-contained Keycloak image. Three inputs are baked in at build time so the production container needs nothing but a database:

  • Stage 1 compiles the keycloakify/ login theme into a Keycloak provider jar.
  • Stage 2 fetches the rockyou leaked-password list.
  • Stage 3 copies the theme jar in and runs kc.sh build - an optimized build pinned to Postgres with health/metrics enabled, so production startup is fast.
  • Stage 4 assembles the runtime image: the optimized server, the blacklist, and the schuly realm import files.

Why an optimized build

kc.sh build resolves the database vendor and feature flags ahead of time. The runtime then starts with start --optimized, skipping the per-boot build step. The trade-off: build-time settings (notably KC_DB) are fixed in the image - changing them means rebuilding. Connection details and the hostname stay runtime env vars. See the Configuration reference.

Request / login flow

The Schuly app authenticates against the schuly realm over OIDC (the schuly-app public client, PKCE). Keycloak serves the branded login pages, enforces the 2FA browser-2fa flow, and persists users and sessions in Postgres. Health and metrics are exposed separately on port 9000 for internal monitoring only.

Source map

See the repository layout table in the docs index for which file owns what.

Edit docs in each source repo — they sync here automatically.