This Helm chart deploys Keycloak on a Kubernetes cluster.
- âś… Customizable Keycloak deployment
- âś… Integrated PostgreSQL database (optional)
- âś… Ingress support with TLS
- âś… Configurable health checks
- âś… Horizontal Pod Autoscaling (HPA)
- âś… Optional data persistence
- âś… Service Account and RBAC
- âś… Proxy configuration for reverse proxy
- âś… External secrets support
- âś… Optional metrics
- Kubernetes 1.19+
- Helm 3.0+
- PersistentVolume provisioner (if persistence is enabled)
The chart is publicly available at oci://quixpublic.azurecr.io/helm/keycloak.
Install a specific version (recommended):
helm install keycloak oci://quixpublic.azurecr.io/helm/keycloak \
--version 1.1.1 \
--namespace keycloak --create-namespaceInstall latest available version:
helm install keycloak oci://quixpublic.azurecr.io/helm/keycloak \
--namespace keycloak --create-namespaceUpgrade:
helm upgrade keycloak oci://quixpublic.azurecr.io/helm/keycloak \
--version 1.1.1 \
--namespace keycloakNote: No login is required for this public registry.
helm install keycloak .helm install keycloak . -f custom-values.yamlkubectl create namespace keycloak
helm install keycloak . --namespace keycloak# Development environment
make install-dev
# Production environment
make install-prod
# Default installation
make install| Parameter | Description | Default |
|---|---|---|
replicaCount |
Number of replicas | 1 |
image.repository |
Image repository | quay.io/keycloak/keycloak |
image.tag |
Image tag | 26.4.0 |
image.pullPolicy |
Pull policy | IfNotPresent |
| Parameter | Description | Default |
|---|---|---|
keycloak.admin.username |
Admin username | admin |
keycloak.admin.password |
Admin password | admin |
keycloak.admin.existingSecret |
Existing secret for admin password | "" |
keycloak.database.vendor |
Database type | postgres |
keycloak.database.host |
Database host | postgresql |
keycloak.database.port |
Database port | 5432 |
keycloak.database.database |
Database name | keycloak |
keycloak.database.username |
Database username | keycloak |
keycloak.database.password |
Database password | keycloak |
keycloak.database.existingSecret |
Existing secret for database credentials | "" |
keycloak.proxy.enabled |
Enable proxy mode (for reverse proxy) | true |
keycloak.proxy.headers |
Proxy headers type (xforwarded or forwarded) | xforwarded |
keycloak.hostname.url |
Public hostname for Keycloak | keycloak.url |
keycloak.hostname.strict |
Enforce strict hostname validation | true |
keycloak.hostname.relativePath |
Relative path for legacy /auth URLs | "" |
keycloak.cache.stack |
Cache stack configuration | "" |
keycloak.health.enabled |
Enable health checks | true |
keycloak.metrics.enabled |
Enable metrics endpoint | false |
keycloak.themes.enabled |
Enable custom themes via init container | false |
| Parameter | Description | Default |
|---|---|---|
ingress.enabled |
Enable Ingress | true |
ingress.className |
Ingress class (only rendered if non-empty) | "" |
ingress.hosts[0].host |
Hostname | keycloak.url |
ingress.tls |
TLS configuration | [] |
| Parameter | Description | Default |
|---|---|---|
postgresql.enabled |
Deploy PostgreSQL | true |
postgresql.image.repository |
PostgreSQL image repository | postgres |
postgresql.image.tag |
PostgreSQL image tag | 15 |
postgresql.annotations |
Pod annotations for PostgreSQL | {} |
postgresql.service.port |
PostgreSQL service port | 5432 |
postgresql.persistence.enabled |
Enable persistence for PostgreSQL | true |
postgresql.persistence.size |
PostgreSQL PVC size | 8Gi |
postgresql.persistence.storageClass |
Storage class for PostgreSQL | "" |
Note: Database credentials are configured via keycloak.database.* settings, not postgresql.auth.*. When postgresql.enabled: true, the chart automatically creates a secret for PostgreSQL authentication.
Use keycloak.extraEnv for custom Keycloak environment variables not covered by the dedicated configuration sections. Common settings like proxy and hostname are now configured via dedicated keycloak.proxy.* and keycloak.hostname.* sections.
keycloak:
# Dedicated configuration (preferred)
proxy:
enabled: true
headers: xforwarded
hostname:
url: keycloak.example.com
strict: true
# Use extraEnv for additional custom variables
extraEnv:
- name: KC_HTTP_ACCESS_LOG
value: "true"
- name: KEYCLOAK_LOGLEVEL
value: INFO
- name: QUARKUS_LOG_LEVEL
value: DEBUGUse keycloak.extraArgs to pass additional command-line arguments to Keycloak:
keycloak:
extraArgs:
- "--spi-theme-static-max-age=-1"
- "--spi-theme-cache-themes=false"
- "--spi-connections-jpa-legacy-initialize-empty=true"# values-ingress.yaml
ingress:
enabled: true
className: nginx
hosts:
- host: keycloak.mydomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: keycloak-tls
hosts:
- keycloak.mydomain.com
keycloak:
hostname:
url: keycloak.mydomain.com
strict: true
proxy:
enabled: true
headers: xforwarded # or 'forwarded' depending on your proxyhelm install keycloak . -f values-ingress.yaml# values-external-db.yaml
postgresql:
enabled: false
keycloak:
database:
host: my-postgres.example.com
port: 5432
database: keycloak
username: keycloak
password: supersecrethelm install keycloak . -f values-external-db.yaml# values-ha.yaml
replicaCount: 3
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
resources:
requests:
cpu: 1000m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
keycloak:
cache:
stack: kuberneteshelm install keycloak . -f values-ha.yaml# values-secrets.yaml
keycloak:
admin:
existingSecret: keycloak-admin-secret
existingSecretKey: password
database:
existingSecret: keycloak-db-secret
existingSecretUsernameKey: username
existingSecretPasswordKey: passwordFirst, create the secrets:
kubectl create secret generic keycloak-admin-secret \
--from-literal=password=myAdminPassword
kubectl create secret generic keycloak-db-secret \
--from-literal=username=keycloak \
--from-literal=password=myDbPasswordThen install:
helm install keycloak . -f values-secrets.yaml# values-metrics.yaml
keycloak:
metrics:
enabled: truehelm install keycloak . -f values-metrics.yamlhelm upgrade keycloak . -f custom-values.yamlOr using the Makefile:
make upgrade-dev # Development
make upgrade-prod # Production
make upgrade # Defaulthelm uninstall keycloakOr:
make uninstallkubectl port-forward svc/keycloak 8080:8080Or:
make port-forwardThen access: http://localhost:8080
- Username: admin
- Password: admin (change in production!)
kubectl logs -f deployment/keycloakOr:
make logskubectl get pods -l app.kubernetes.io/name=keycloakkubectl get secretskubectl get secret keycloak-admin -o jsonpath="{.data.password}" | base64 --decodeOr:
make get-admin-passwordkubectl exec -it deployment/keycloak -- /bin/bashmake help # Show all available targets
make install # Install with default values
make install-dev # Install with development values
make install-prod # Install with production values
make upgrade # Upgrade existing installation
make uninstall # Remove the installation
make template # Generate manifests without installing
make lint # Lint the chart
make port-forward # Port-forward to Keycloak service
make logs # Show Keycloak logs
make status # Show release status
make get-admin-password # Get admin password from secretUse values-development.yaml for local development:
- Single replica
- Minimal resources
- Bundled PostgreSQL without persistence
- No Ingress
- Debug logging enabled
make install-devUse values-production.yaml for production:
- 3 replicas with autoscaling
- High availability configuration
- External database
- Ingress with TLS
- Metrics enabled
- Pod anti-affinity rules
make install-prod- Change default passwords before deploying to production
- Use external secrets instead of storing passwords in
values.yaml - Enable TLS on Ingress
- Configure appropriate resource limits
- Review pod security policies
- Use strong admin credentials
- Enable HTTPS for production deployments
- Implement network policies if required
Enable metrics in your values file:
keycloak:
metrics:
enabled: trueMetrics will be available on port 9000 and can be scraped by Prometheus.
The chart includes PostgreSQL by default:
postgresql:
enabled: true
keycloak:
database:
username: keycloak
password: keycloak
database: keycloakNote: Database credentials are configured in keycloak.database.*, not postgresql.auth.*.
For production, use an external database:
postgresql:
enabled: false
keycloak:
database:
host: your-postgres-host.com
port: 5432
database: keycloak
username: keycloak
existingSecret: keycloak-db-secret- PostgreSQL
Configure the database vendor in keycloak.database.vendor.
For HA deployments:
- Set
replicaCountto 3 or more - Enable
autoscaling - Configure
cache.stacktokubernetes - Use external database
- Configure pod anti-affinity rules
replicaCount: 3
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
keycloak:
cache:
stack: kubernetesTo add custom themes, enable the themes feature and configure an init container:
keycloak:
themes:
enabled: true
volumeName: keycloak-themes # Name of the shared volume
initContainer:
image: your-themes-image:latest # Image containing your custom themes
command:
- sh
- -c
- cp -R /source-themes/* /themes/
volumeMounts: [] # Additional volume mounts if needed
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 50m
memory: 64MiThe init container will:
- Run before Keycloak starts
- Copy theme files to
/opt/keycloak/themes/(mounted as emptyDir) - Make themes available to the Keycloak container
You can also use a ConfigMap for theme configuration:
keycloak:
themes:
enabled: true
configMap: my-theme-configThis chart includes comprehensive support for Microsoft Entra ID integration. See the detailed guides:
- Microsoft Entra ID Integration Guide - Complete step-by-step configuration
- Quick Start Guide - Fast-track setup (20 minutes)
- values-microsoft-entra.yaml - Pre-configured values file
Quick deployment with Microsoft Entra ID support:
# Create secrets first
kubectl create secret generic keycloak-admin-credentials --from-literal=password='YourPassword'
kubectl create secret generic keycloak-db-credentials --from-literal=username='keycloak' --from-literal=password='DBPassword'
# Deploy
helm install keycloak . -f values-microsoft-entra.yaml --namespace keycloak --create-namespaceAfter deployment, follow the integration guide to configure the identity provider.
Keycloak supports integration with many identity providers:
- GitHub
- SAML providers
- LDAP/Active Directory
- Custom OpenID Connect providers
Refer to Keycloak's Identity Brokering documentation for configuration details.
Contributions are welcome! Please feel free to submit a Pull Request.
This Helm chart is open source. Keycloak is licensed under the Apache 2.0 License.
- Keycloak Official Documentation
- Keycloak GitHub Repository
- Helm Documentation
- Microsoft Entra ID Integration
For issues and questions:
- Keycloak: https://github.com/keycloak/keycloak/issues
- This Chart: Create an issue in the repository