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

  1. Log in at https://id.example.com/admin with the bootstrap admin. Create a permanent admin user in the master realm, then remove the temporary one.
  2. Create a realm for your organisation (e.g. company). Don’t put your users in master.
  3. Realm settings: email (SMTP), login options (forgot password, remember me), and themes.
  4. Authentication → Required actions / flows: require OTP for everyone, or for specific roles. Enable WebAuthn / passkeys.
  5. 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.

  • Self-Hosting
  • Security
  • Authentication