Skip to Content

Self-Host Keycloak: Enterprise SSO for Your Homelab in 15 Minutes

Tired of managing separate logins for every self-hosted service? Keycloak gives you enterprise-grade Single Sign-On (SSO) for your entire homelab — free, open-source, and under your control.

Why Self-Host Keycloak?

If you're running more than a handful of services, you've felt the pain: different passwords for Grafana, Portainer, Nextcloud, and every other tool. Password managers help, but they don't solve the real problem — identity sprawl.

Keycloak is an open-source Identity and Access Management (IAM) solution that centralizes authentication across all your services. One login. One password. One place to manage users, roles, and security policies.

What you get:

  • Single Sign-On (SSO) — Log in once, access everything
  • OIDC & SAML support — Works with virtually any modern application
  • Two-Factor Authentication (2FA) — TOTP, WebAuthn, and more built-in
  • User Federation — Connect to existing LDAP or Active Directory
  • Social Login — Google, GitHub, GitLab as identity providers
  • Fine-grained Authorization — Role-based access control (RBAC)

Unlike cloud identity providers, you own your data. No third-party dependencies, no subscription fees, no vendor lock-in.

Prerequisites

  • A VPS or server with 2+ CPU cores, 2GB+ RAM (Keycloak is Java-based and memory-hungry)
  • Docker and Docker Compose installed
  • A domain name pointed to your server (for HTTPS)
  • Reverse proxy like Traefik or Nginx (recommended for production)

Step 1: Create the Docker Compose File

Create a directory for Keycloak and a docker-compose.yml file:

version: '3.8'

services:
  keycloak:
    image: quay.io/keycloak/keycloak:24.0
    container_name: keycloak
    command: start-dev
    environment:
      KC_HOSTNAME: auth.yourdomain.com
      KC_HOSTNAME_STRICT_BACKCHANNEL: "true"
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: your-secure-admin-password
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: keycloak-db-password
    ports:
      - "8080:8080"
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - keycloak-network

  postgres:
    image: postgres:16-alpine
    container_name: keycloak-postgres
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: keycloak-db-password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U keycloak"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - keycloak-network

volumes:
  postgres_data:

networks:
  keycloak-network:
    driver: bridge

Important: Replace auth.yourdomain.com, your-secure-admin-password, and keycloak-db-password with your actual values.

Step 2: Start Keycloak

Launch the stack:

docker compose up -d

Wait 30-60 seconds for Keycloak to initialize. Check logs if needed:

docker logs -f keycloak

You should see Listening on: http://0.0.0.0:8080 when ready.

Step 3: Initial Setup

  1. Open http://your-server-ip:8080 in your browser
  2. Click Administration Console
  3. Log in with admin / your admin password

You'll land in the master realm. Important: Create a dedicated realm for your applications instead of using master:

  1. Hover over the realm dropdown (top-left) → Click Create Realm
  2. Name it homelab (or whatever you prefer)
  3. Click Create

Step 4: Configure Your First Client

A "client" in Keycloak represents an application that will use it for authentication. Let's set up Grafana as an example:

  1. In your realm, go to Clients → Create client
  2. Client ID: grafana
  3. Client authentication: On (confidential)
  4. Authentication flow: Enable Standard flow (authorization code)
  5. Valid redirect URIs: https://grafana.yourdomain.com/login/generic_oauth
  6. Save, then go to the Credentials tab and copy the Client Secret

Now configure Grafana's docker-compose.yml:

environment:
  GF_AUTH_GENERIC_OAUTH_ENABLED: "true"
  GF_AUTH_GENERIC_OAUTH_NAME: Keycloak
  GF_AUTH_GENERIC_OAUTH_CLIENT_ID: grafana
  GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: your-client-secret-here
  GF_AUTH_GENERIC_OAUTH_SCOPES: openid email profile
  GF_AUTH_GENERIC_OAUTH_AUTH_URL: https://auth.yourdomain.com/realms/homelab/protocol/openid-connect/auth
  GF_AUTH_GENERIC_OAUTH_TOKEN_URL: https://auth.yourdomain.com/realms/homelab/protocol/openid-connect/token
  GF_AUTH_GENERIC_OAUTH_API_URL: https://auth.yourdomain.com/realms/homelab/protocol/openid-connect/userinfo
  GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP: "true"

Restart Grafana. You'll now see a "Sign in with Keycloak" button on the login page.

Step 5: Add Users

  1. Go to Users → Add user
  2. Username: ali (or your preferred username)
  3. Email: your email
  4. Save, then go to the Credentials tab
  5. Set a password (disable "Temporary" if you want it permanent)

The user can now log in to any configured client with these credentials.

Step 6: Enable Two-Factor Authentication (Optional but Recommended)

  1. Go to Authentication → Required Actions
  2. Enable Configure OTP as a default action

Now every user will be prompted to set up TOTP (Google Authenticator, Authy, etc.) on first login.

Production Hardening

The setup above uses start-dev mode. For production:

  1. Use a reverse proxy (Traefik/Nginx) with HTTPS — Keycloak requires secure connections in production
  2. Switch to start mode and configure TLS certificates
  3. Enable production database — PostgreSQL (included above) is recommended over the default H2
  4. Configure email — Go to Realm Settings → Email for password resets and notifications
  5. Set up backups — Export your realm regularly: docker exec keycloak /opt/keycloak/bin/kc.sh export --dir /tmp/export

Verification Checklist

  • ✅ Keycloak admin console accessible at your domain
  • ✅ Dedicated realm created (not using master)
  • ✅ Test user can log in to admin console
  • ✅ Grafana (or another client) shows "Sign in with Keycloak"
  • ✅ OAuth redirect works end-to-end
  • ✅ 2FA prompt appears if configured

Next Steps

  • Add more clients — Portainer, Nextcloud, MinIO, and most modern apps support OIDC
  • Social login — Connect Google/GitHub under Identity Providers
  • Groups & roles — Map Keycloak groups to application roles for fine-grained access
  • LDAP federation — If you have an existing directory, sync users instead of recreating them

Related Guides

Centralized identity isn't just convenient — it's a security upgrade. One strong password with 2FA beats a dozen weak ones scattered across services. Your future self will thank you.

Self-Host Traefik: The Ultimate Reverse Proxy for Your Homelab in 20 Minutes