Keycloak is a widely used open-source identity and access management server. It gives your applications single sign-on via OpenID Connect and SAML, multi-factor authentication, user federation with LDAP or Active Directory, social logins, fine-grained roles, and self-service account management. If you build or run several apps that need shared logins, Keycloak becomes your central identity provider.
Lighter alternatives: Authelia (forward auth plus simple OIDC), Authentik and Zitadel.
Requirements
- 2 vCPU, 2–4 GB RAM (Keycloak runs on the JVM).
- PostgreSQL (recommended), or MySQL/MariaDB.
- A domain, e.g.
id.example.com, with HTTPS.
Docker Compose (production mode)
# /opt/keycloak/compose.yaml
services:
keycloak:
image: quay.io/keycloak/keycloak:26.1
restart: unless-stopped
command: start --optimized
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://db:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: change-me-db
KC_HOSTNAME: https://id.example.com
KC_HTTP_ENABLED: "true" # TLS terminated at Nginx
KC_PROXY_HEADERS: xforwarded
KC_HEALTH_ENABLED: "true"
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: change-me-temporary
ports:
- "127.0.0.1:8080:8080"
depends_on: [db]
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: change-me-db
volumes:
- ./postgres:/var/lib/postgresql/data
start --optimized needs a pre-built image. For simplicity, use start (without --optimized), which builds on startup and starts more slowly. Variable names changed across Keycloak versions (e.g. the bootstrap admin), so check the docs for your version.
cd /opt/keycloak && docker compose up -d
Nginx with HTTPS
server {
server_name id.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
}
# listen 443 ssl; certbot --nginx -d id.example.com
}
Larger proxy buffers prevent errors with big tokens and cookies. Consider restricting /admin to admin IPs or a VPN. See Let’s Encrypt.
First steps in the admin console
- Log in at
https://id.example.com/adminwith the bootstrap admin. Create a permanent admin user in themasterrealm, then remove the temporary one. - Create a realm for your organisation (e.g.
company). Don’t put your users inmaster. - Realm settings: email (SMTP), login options (forgot password, remember me), and themes.
- Authentication → Required actions / flows: require OTP for everyone, or for specific roles. Enable WebAuthn / passkeys.
- Users and groups: create them, or connect LDAP/Active Directory (User federation). See OpenLDAP.
Connect an application (OIDC client)
Clients → Create client:
- client type OpenID Connect, with a client ID like
grafana; - client authentication on (confidential client) for server-side apps;
- valid redirect URIs: exact URLs, like
https://grafana.example.com/login/generic_oauth; - copy the client secret from the Credentials tab.
The app then uses Keycloak’s discovery URL:
https://id.example.com/realms/company/.well-known/openid-configuration
Map roles or groups into tokens (client scopes / mappers), so apps can authorise users. See OAuth 2.0 and OIDC explained.
Apps without OIDC support can be protected with an OIDC-aware proxy (oauth2-proxy) in front.
Social and external logins
Identity providers let users sign in with Google, GitHub or Microsoft, or with another OIDC or SAML provider, while Keycloak stays the central place for roles and sessions.
Operations
- Backups: PostgreSQL dumps, plus realm exports for configuration. See pg_dump.
docker compose exec -T db pg_dump -U keycloak keycloak > /backups/keycloak-$(date +%F).sql
- Upgrades: follow the migration guide for each major version, and back up first. Keycloak upgrades the database schema automatically. See updating self-hosted apps.
- Monitoring: health endpoints (
/health/ready) on the management port, and metrics when enabled. - Security: MFA for admins, brute-force detection (Realm settings → Security defenses), short token lifetimes, and HTTPS only.
Quick reference
| Item | Value |
|---|---|
| Admin console | /admin |
| Discovery URL | /realms/REALM/.well-known/openid-configuration |
| Proxy headers | KC_PROXY_HEADERS=xforwarded |
| Hostname | KC_HOSTNAME=https://id.example.com |
| Database | PostgreSQL (KC_DB=postgres) |
Related: zero trust networking and SSH certificates.