Skip to content

Keycloak

Keycloak running

Identity and access management

Version
26.4.7
External
https://auth.wighttrash.uk
ItemDetail
Compose file/opt/keycloak/docker-compose.yml
DatabasePostgreSQL 16 (container: keycloak-postgres)
Reverse proxyTraefik (Pangolin stack) via dynamic_config.yml
Imagekeycloak-local:latest (optimised build from quay.io/keycloak/keycloak:26.4.7)

Keycloak runs on the Netcup VPS alongside Pangolin. Cloudflare terminates TLS at the edge. Traefik routes auth.wighttrash.uk to the Keycloak container on port 8080. Keycloak runs plain HTTP internally, which is correct for an edge-terminated setup.

flowchart TD INT([Internet]) CF["Cloudflare TLS terminated at edge"] TR["Traefik Pangolin stack"] KC["Keycloak container HTTP port 8080"] PG[("PostgreSQL internal Docker network")] INT --> CF CF -->|"auth.wighttrash.uk → 152.53.226.118:443"| TR TR -->|"routes to keycloak:8080"| KC KC --- PG

/opt/keycloak/
├── docker-compose.yml
├── .env <- secrets, chmod 600, never commit
├── Dockerfile <- optimised build image
└── data/
└── import/

An optimised build image is used for fast startup. Rebuild when upgrading Keycloak or changing build-time options.

FROM quay.io/keycloak/keycloak:26.4.7 AS builder
ENV KC_DB=postgres
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_FEATURES=token-exchange
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:26.4.7
COPY --from=builder /opt/keycloak/ /opt/keycloak/
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

Rebuild command:

Terminal window
cd /opt/keycloak
docker build -t keycloak-local:latest .

The master realm is used for admin access only. All applications use the wighttrash realm.

RealmPurpose
masterAdmin console access only
wighttrashAll application authentication (Immich, Jellyfin, Pangolin, Docs wiki)

Do not register applications in the master realm.


Two accounts exist following a break-glass pattern.

AccountRealmAuth methodPurpose
kcadminmasterUsername/password + TOTPBreak-glass - use if Keycloak social login is unavailable
[email protected]masterSocial login (Entra ID)Day-to-day admin access

Day-to-day admin work uses [email protected] via https://auth.wighttrash.uk/admin/master/console. The kcadmin account is kept as a fallback in case Keycloak’s own authentication is unavailable.


Both providers are configured in the wighttrash realm under Identity Providers.

ProviderAliasTrust emailSync modeFirst login flow
GooglegoogleOnForceauto link existing only
Microsoft (Entra)microsoftOnForceauto link existing only

The auto link existing only flow is a custom Basic flow with two steps, both Required.

Step 1. Detect existing broker user - checks whether a Keycloak account with the same email exists in the realm. If no match is found, the flow fails and the user is blocked. No new accounts are created.

Step 2. Automatically set existing user - links the social login to the matched Keycloak account with no further challenge.

To allow a new user to sign in via social, create them in the wighttrash realm first under Users, set Email verified to On, and do not set a password. The social provider will be linked automatically on first login.


Client ID Name Auth method Redirect URIs Post logout URI
immich Immich Social (Google / Microsoft via Keycloak)
  • https://photos.wighttrash.uk/auth/login
  • https://photos.wighttrash.uk/api/oauth/mobile-redirect
  • https://photos.wighttrash.uk/user-settings
https://photos.wighttrash.uk
jellyfin Jellyfin Social (Google / Microsoft via Keycloak)
  • org.jellyfin.mobile://login-callback
  • https://media.wighttrash.uk/sso/OID/redirect/keycloak
https://media.wighttrash.uk/
pangolin Pangolin Social (Google / Microsoft) + break-glass password / MFA
  • https://pangolin.wighttrash.uk/auth/idp/1/oidc/callback
https://pangolin.wighttrash.uk
docs-wiki Docs Wiki (Cloudflare Access) Social (Google / Microsoft via Keycloak)
  • https://wighttrash.cloudflareaccess.com/cdn-cgi/access/callback
https://docs.wighttrash.uk
planka Planka Keycloak OIDC (social login)
  • https://planka.wighttrash.uk/oidc-callback
https://planka.wighttrash.uk
web OpenCloud Web Keycloak OIDC / PKCE S256 (realm roles via opencloud-roles mapper)
  • https://cloud.wighttrash.uk
  • https://cloud.wighttrash.uk/oidc-callback.html
  • https://cloud.wighttrash.uk/oidc-silent-redirect.html
https://cloud.wighttrash.uk
OpenCloudAndroid OpenCloud Android Keycloak OIDC / PKCE S256
  • oc://android.opencloud.eu
-
OpenCloudDesktop OpenCloud Desktop Keycloak OIDC / PKCE S256
  • http://127.0.0.1
  • http://localhost
-
OpenCloudIOS OpenCloud iOS Keycloak OIDC / PKCE S256
  • oc://ios.opencloud.eu
oc://ios.opencloud.eu

All clients are confidential (client authentication on, standard flow only).


https://auth.wighttrash.uk/realms/wighttrash/.well-known/openid-configuration
EndpointURL
Authorizationhttps://auth.wighttrash.uk/realms/wighttrash/protocol/openid-connect/auth
Tokenhttps://auth.wighttrash.uk/realms/wighttrash/protocol/openid-connect/token
Issuerhttps://auth.wighttrash.uk/realms/wighttrash

ItemStatus
Bootstrap admin deleted, permanent admin createdDone
User self-registration disabledDone
Email verification enabledDone
Login with email enabledDone
Brute force detection enabled (max 5 failures, 15 min lockout)Done
Session timeouts configured (SSO 8h, access token 5 min, refresh 30 min)Done
Port 9000 (health/metrics) not exposed publiclyDone
Port 8080 (HTTP) not exposed directly - Traefik onlyDone
.env is chmod 600Done
Image pinned to 26.4.7Done

Terminal window
# Manual dump
docker exec keycloak-postgres pg_dump -U keycloak keycloak \
> /opt/keycloak/backup-$(date +%Y%m%d).sql
# Restore
docker exec -i keycloak-postgres psql -U keycloak keycloak \
< /opt/keycloak/backup-YYYYMMDD.sql

Terminal window
# View logs
docker logs -f keycloak
# Check health (from inside VPS)
curl -s http://localhost:9000/health/ready
# Restart stack
cd /opt/keycloak && docker compose restart
# Rebuild image (after version change)
cd /opt/keycloak && docker build -t keycloak-local:latest .

Step 1. Update the version tag in /opt/keycloak/Dockerfile.

Step 2. Back up PostgreSQL (see above).

Step 3. Rebuild the image:

Terminal window
docker build -t keycloak-local:latest .

Step 4. Start the updated stack:

Terminal window
docker compose up -d

Step 5. Watch logs to confirm startup:

Terminal window
docker logs -f keycloak

Step 6. Verify the OIDC discovery endpoint is responding:

Terminal window
curl -s https://auth.wighttrash.uk/realms/wighttrash/.well-known/openid-configuration

Keycloak will not start. Check logs with docker logs keycloak --tail 100. Common causes are database not ready or misconfigured KC_HOSTNAME.

503 from Traefik. Confirm Keycloak is running (docker ps) and that the IP in dynamic_config.yml matches the container’s current IP on the pangolin network (docker network inspect pangolin).

Social login denied with “invalid username or password”. The user’s email does not exist in the wighttrash realm. Create the user in the Admin Console first.

Locked out of admin console. Go directly to https://auth.wighttrash.uk/admin/master/console and sign in with kcadmin. This bypasses the wighttrash realm entirely.