Skip to content

Quick Start

Goal: go from zero to a browser-accessible Keycloak instance with BYO PostgreSQL in a few minutes.

This is the golden path — one KeycloakInstance, a bring-your-own Postgres Secret, one admin login. For the full configuration surface (managed Postgres, providers, ingress/TLS, realm import), see the KeycloakInstance Guide.

Prerequisites

Requirement Why Check
Kubernetes 1.25+ CRD + status subresource support kubectl version
The operator installed Reconciles KeycloakInstance kubectl get pods -n bnerd-keycloak-system
A reachable PostgreSQL instance Keycloak's database —
Ingress controller (optional for this quick start) External access kubectl get ingressclass

The Installation page covers installing the operator itself and its optional backend prerequisites. This quick start uses spec.ingress.enabled: false so an ingress controller is not required — you'll reach Keycloak via kubectl port-forward instead.

Step 1 — Apply the default KeycloakVersionMap

The operator always looks up the cluster-scoped KeycloakVersionMap named default to resolve spec.version to a container image. If you installed via Helm with versionMap.installDefault: true (the default), this is already done — verify:

kubectl get kcvm default
# NAME      LATEST    AGE
# default   26.8.1    5s

Otherwise apply it once per cluster:

kubectl apply -f examples/versionmap-default.yaml

Step 2 — Create a namespace, a Postgres credentials Secret, and a KeycloakInstance

Replace keycloak-dev.example.com with your real DNS name (it's used to set KC_HOSTNAME even with ingress disabled) and the Postgres values with a reachable database.

# keycloak-quickstart.yaml
apiVersion: v1
kind: Secret
metadata:
  name: my-keycloak-pg-credentials
  namespace: my-keycloak
stringData:
  host: postgres.my-keycloak.svc.cluster.local
  dbname: keycloak
  user: keycloak
  password: change-me
---
apiVersion: k8s.bnerd.com/v1alpha1
kind: KeycloakInstance
metadata:
  name: my-keycloak
  namespace: my-keycloak
spec:
  version: "stable"
  replicas: 1

  hosts:
    host: keycloak-dev.example.com

  ingress:
    enabled: false   # Services only; reach via port-forward below

  postgres:
    managed: false
    credentialsSecret: my-keycloak-pg-credentials

Create the namespace and apply:

kubectl create namespace my-keycloak
kubectl apply -f keycloak-quickstart.yaml

Want managed Postgres instead?

Set postgres.managed: true and drop credentialsSecret — the operator provisions a PerconaPGCluster for you (requires the Percona PG Operator, see Installation). See examples/keycloakinstance-full.yaml for a full managed-HA example.

Step 3 — Watch the instance come up

kubectl get kci -n my-keycloak -w
# NAME          PHASE          HOST                        VERSION   AGE
# my-keycloak   Provisioning                                         10s
# my-keycloak   Deploying      keycloak-dev.example.com              45s
# my-keycloak   Ready          keycloak-dev.example.com    26.6.4    90s

The phase sequence is Pending → Provisioning (backend credentials being resolved) → Deploying (StatefulSet applied, rollout converging) → Ready. Ready is only reported once the StatefulSet rollout has fully converged onto the new revision — no old-revision pods still serving.

If it stays in a non-Ready phase for more than a couple of minutes, see Troubleshooting.

Step 4 — Get the admin bootstrap credentials

Because spec.adminSecret was omitted, the operator generated <name>-admin-credentials for you:

kubectl get secret my-keycloak-admin-credentials -n my-keycloak \
  -o jsonpath='{.data.username}' | base64 -d; echo
kubectl get secret my-keycloak-admin-credentials -n my-keycloak \
  -o jsonpath='{.data.password}' | base64 -d; echo

Step 5 — Reach Keycloak

With ingress.enabled: false, port-forward the client Service:

kubectl port-forward -n my-keycloak svc/my-keycloak 8080:8080

Open http://localhost:8080 and log in to the admin console with the username/password from Step 4.

This quick start is dev-only

No Ingress/TLS is configured and the port-forward path is not suitable for production traffic. See KeycloakInstance Guide for enabling Ingress with cert-manager TLS.

What's next