Deploy Keycloak

Get started with Keycloak on Docker for dev environment

docker run -p 8080:8080 -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:26.0.5 start-dev

This command starts Keycloak exposed on the local port 8080 and creates an initial admin user with the username admin and password admin.

Kubernetes Production Deployment

For production environments it is highly recommended to deploy Keycloak via Operator.

Install the CRDs by entering the following commands:

kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/26.0.5/kubernetes/keycloaks.k8s.keycloak.org-v1.yml
kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/26.0.5/kubernetes/keycloakrealmimports.k8s.keycloak.org-v1.yml

Install the Keycloak Operator deployment by entering the following command:

kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/26.0.5/kubernetes/kubernetes.yml

Preparing for deployment

Once the Keycloak Operator is installed and running in the cluster namespace, you can set up the other deployment prerequisites.

  • Database
  • Hostname
  • TLS Certificate and associated keys

TLS Certificate and key

For development purposes, you can enter this command to obtain a self-signed certificate:

openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
kubectl create secret tls example-tls-secret --cert certificate.pem --key key.pem -n $namespace

Deploying Keycloak

To deploy Keycloak, you create a Custom Resource (CR) based on the Keycloak Custom Resource Definition (CRD).

Consider storing the Database credentials in a separate Secret. Enter the following commands:

kubectl create secret generic keycloak-db-secret \
  --from-literal=username=[your_database_username] \
  --from-literal=password=[your_database_password] -n $namespace
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: example-kc
spec:
  instances: 1
  db:
    vendor: postgres
    host: postgres-db
    usernameSecret:
      name: keycloak-db-secret
      key: username
    passwordSecret:
      name: keycloak-db-secret
      key: password
  http:
    tlsSecret: example-tls-secret
  hostname:
    hostname: test.keycloak.org
  proxy:
    headers: xforwarded # double check your reverse proxy sets and overwrites the X-Forwarded-* headers
 kubectl apply -f example-keycloak.yaml -n $namespace

Deploy with Ingress Configuration

apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
  name: pot-auth
spec:
  instances: 1
  image: ghcr.io/eclipse-iofog/keycloak:25.0.0
  startOptimized: false
  db:
    vendor: 
    usernameSecret:
      name: 
      key: 
    passwordSecret:
      name: 
      key: 
    host:
    database: 
    port: 
  http:
    httpEnabled: false
    httpsPort: 8443
    tlsSecret: kc-auth
  hostname:
    hostname: kc.example.com
  ingress:
    enabled: false
  additionalOptions:
    - name: proxy
      value: reencrypt
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pot-auth-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/backend-protocol: "https"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - kc.example.com
    secretName: kc-auth
  rules:
  - host: kc.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pot-auth
            port:
              number: 8443