Install and configure Keycloak for enterprise authentication with clustering

Intermediate 45 min Apr 01, 2026 43 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Set up Keycloak as an enterprise identity provider with PostgreSQL backend, SSL encryption, and high availability clustering for OAuth2, OpenID Connect, and SAML authentication across your organization.

Prerequisites

  • Root or sudo access
  • 2GB+ RAM recommended
  • PostgreSQL database
  • Valid domain name for SSL
  • Open ports 8080, 8443, 7800

What this solves

Keycloak provides centralized identity and access management for enterprise applications, supporting OAuth2, OpenID Connect, and SAML protocols. This tutorial configures a production-ready Keycloak cluster with PostgreSQL database backend, SSL encryption, LDAP integration, and high availability clustering for enterprise environments.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions and security patches.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Java 17

Keycloak requires Java 17 or later. Install OpenJDK 17 which provides the best compatibility and performance.

sudo apt install -y openjdk-17-jdk wget curl unzip
java -version
sudo dnf install -y java-17-openjdk java-17-openjdk-devel wget curl unzip
java -version

Create keycloak user and directories

Create a dedicated system user for running Keycloak services and set up the directory structure with proper permissions.

sudo useradd -r -s /bin/false keycloak
sudo mkdir -p /opt/keycloak
sudo mkdir -p /var/log/keycloak
sudo mkdir -p /etc/keycloak

Download and install Keycloak

Download the latest Keycloak distribution and extract it to the installation directory.

cd /tmp
wget https://github.com/keycloak/keycloak/releases/download/24.0.1/keycloak-24.0.1.tar.gz
sudo tar -xzf keycloak-24.0.1.tar.gz -C /opt
sudo mv /opt/keycloak-24.0.1/* /opt/keycloak/
sudo chown -R keycloak:keycloak /opt/keycloak
sudo chown -R keycloak:keycloak /var/log/keycloak
sudo chmod 755 /opt/keycloak
sudo chmod 755 /var/log/keycloak

Install and configure PostgreSQL

Set up PostgreSQL as the database backend for Keycloak. This provides better performance and reliability than the default H2 database.

sudo apt install -y postgresql postgresql-contrib
sudo systemctl enable --now postgresql
sudo dnf install -y postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql

Create Keycloak database and user

Create a dedicated database and user for Keycloak with appropriate permissions.

sudo -u postgres createdb keycloak
sudo -u postgres psql -c "CREATE USER keycloak WITH ENCRYPTED PASSWORD 'KC_SecurePass2024!';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;"
sudo -u postgres psql -c "ALTER DATABASE keycloak OWNER TO keycloak;"

Download PostgreSQL JDBC driver

Keycloak needs the PostgreSQL JDBC driver to connect to the database.

sudo mkdir -p /opt/keycloak/providers
cd /tmp
wget https://jdbc.postgresql.org/download/postgresql-42.7.1.jar
sudo mv postgresql-42.7.1.jar /opt/keycloak/providers/
sudo chown keycloak:keycloak /opt/keycloak/providers/postgresql-42.7.1.jar

Configure Keycloak database connection

Create the main Keycloak configuration file with database settings and clustering configuration.

# Database configuration
db=postgres
db-url=jdbc:postgresql://localhost:5432/keycloak
db-username=keycloak
db-password=KC_SecurePass2024!

HTTP/HTTPS configuration

http-host=0.0.0.0 http-port=8080 https-port=8443 hostname-strict=false hostname-strict-https=false

Clustering configuration

cache=ispn cache-stack=tcp cluster-stack=tcp

Logging

log-level=INFO log-file=/var/log/keycloak/keycloak.log

Health and metrics

health-enabled=true metrics-enabled=true

Features

features=account2,account-api,admin-fine-grained-authz,admin2,authorization,ciba,client-policies,declarative-user-profile,docker,impersonation,openshift-integration,scripts,token-exchange,web-authn

Set proper ownership and permissions for the configuration file.

sudo chown keycloak:keycloak /opt/keycloak/conf/keycloak.conf
sudo chmod 600 /opt/keycloak/conf/keycloak.conf

Build Keycloak with custom configuration

Build Keycloak with the PostgreSQL driver and configuration optimizations.

cd /opt/keycloak
sudo -u keycloak /opt/keycloak/bin/kc.sh build

Install SSL certificates with Let's Encrypt

Install Certbot to obtain SSL certificates for secure HTTPS communication.

sudo apt install -y certbot
sudo certbot certonly --standalone -d auth.example.com --email admin@example.com --agree-tos --non-interactive
sudo dnf install -y certbot
sudo certbot certonly --standalone -d auth.example.com --email admin@example.com --agree-tos --non-interactive

Configure SSL keystore

Convert Let's Encrypt certificates to Java keystore format for Keycloak.

sudo mkdir -p /opt/keycloak/conf/ssl
sudo openssl pkcs12 -export -in /etc/letsencrypt/live/auth.example.com/fullchain.pem -inkey /etc/letsencrypt/live/auth.example.com/privkey.pem -out /tmp/keystore.p12 -name keycloak -passout pass:KeystorePass2024!
sudo keytool -importkeystore -deststorepass KeystorePass2024! -destkeypass KeystorePass2024! -destkeystore /opt/keycloak/conf/ssl/keycloak.jks -srckeystore /tmp/keystore.p12 -srcstoretype PKCS12 -srcstorepass KeystorePass2024! -alias keycloak
sudo chown -R keycloak:keycloak /opt/keycloak/conf/ssl
sudo chmod 600 /opt/keycloak/conf/ssl/keycloak.jks
sudo rm /tmp/keystore.p12

Update configuration for HTTPS

Add SSL keystore configuration to the Keycloak configuration file.

sudo tee -a /opt/keycloak/conf/keycloak.conf > /dev/null << 'EOF'

SSL/TLS configuration

https-certificate-file=/etc/letsencrypt/live/auth.example.com/fullchain.pem https-certificate-key-file=/etc/letsencrypt/live/auth.example.com/privkey.pem hostname=auth.example.com EOF

Create systemd service

Create a systemd service file to manage Keycloak as a system service with proper resource limits and security settings.

[Unit]
Description=Keycloak Identity Provider
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=exec
User=keycloak
Group=keycloak
ExecStart=/opt/keycloak/bin/kc.sh start --optimized
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s

Security settings

NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ReadWritePaths=/var/log/keycloak /opt/keycloak/data

Resource limits

LimitNOFILE=65536 LimitNPROC=32768

Environment

Environment=JAVA_OPTS="-Xms1g -Xmx2g -XX:MetaspaceSize=96m -XX:MaxMetaspaceSize=256m" Environment=KC_LOG_FILE=/var/log/keycloak/keycloak.log

Working directory

WorkingDirectory=/opt/keycloak [Install] WantedBy=multi-user.target

Configure firewall rules

Open the necessary ports for Keycloak HTTP, HTTPS, and clustering communication.

sudo ufw allow 8080/tcp comment 'Keycloak HTTP'
sudo ufw allow 8443/tcp comment 'Keycloak HTTPS'
sudo ufw allow 7800/tcp comment 'Keycloak clustering'
sudo ufw allow 57800/tcp comment 'Keycloak clustering multicast'
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8443/tcp
sudo firewall-cmd --permanent --add-port=7800/tcp
sudo firewall-cmd --permanent --add-port=57800/tcp
sudo firewall-cmd --reload

Start and enable Keycloak

Enable and start the Keycloak service, then check its status to ensure it's running properly.

sudo systemctl daemon-reload
sudo systemctl enable --now keycloak
sudo systemctl status keycloak
sudo journalctl -u keycloak -f

Create initial admin user

Create the first admin user for accessing the Keycloak admin console.

cd /opt/keycloak
sudo -u keycloak /opt/keycloak/bin/kc.sh start --optimized &
sleep 30
sudo -u keycloak KEYCLOAK_ADMIN=admin KEYCLOAK_ADMIN_PASSWORD='AdminPass2024!' /opt/keycloak/bin/kc.sh start --optimized
sudo pkill -f keycloak
sudo systemctl start keycloak

Configure clustering for high availability

For the second node in your cluster, modify the configuration to enable clustering. On the second server, follow all previous steps and modify the configuration.

# Add these lines for clustering on second node
cache=ispn
cache-stack=tcp
cluster-stack=tcp
cluster=keycloak-cluster

JGroups TCP configuration

kc.spi-connections-jpa-default-url=jdbc:postgresql://203.0.113.10:5432/keycloak kc.spi-connections-jpa-default-username=keycloak kc.spi-connections-jpa-default-password=KC_SecurePass2024!

Cluster discovery

kc.cache-config-file=cluster-tcp.xml

Configure LDAP integration

Set up LDAP user federation through the admin console. Access https://auth.example.com:8443/admin and navigate to User Federation.

Note: LDAP configuration is done through the web interface at Configure > User Federation > Add LDAP provider. Use these typical settings for Active Directory integration: Connection URL (ldap://203.0.113.20:389), Bind DN (CN=keycloak,CN=Users,DC=company,DC=local), Users DN (CN=Users,DC=company,DC=local).

Configure reverse proxy with NGINX

Set up NGINX as a reverse proxy for SSL termination and load balancing. You can reference our NGINX configuration tutorial for detailed setup.

upstream keycloak {
    server 127.0.0.1:8080;
    # Add second node for clustering
    # server 203.0.113.11:8080;
}

server {
    listen 443 ssl http2;
    server_name auth.example.com;
    
    ssl_certificate /etc/letsencrypt/live/auth.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/auth.example.com/privkey.pem;
    
    location / {
        proxy_pass http://keycloak;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
        
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
    }
}

server {
    listen 80;
    server_name auth.example.com;
    return 301 https://$server_name$request_uri;
}

Performance tuning and security hardening

Configure JVM memory settings

Optimize JVM settings for production workloads based on your server resources.

# Add JVM options for production
kc.java-opts=-Xms2g -Xmx4g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true

Configure security headers

Add security headers and configure secure session settings through the admin console or configuration.

sudo tee -a /opt/keycloak/conf/keycloak.conf > /dev/null << 'EOF'

Security settings

kc.spi-login-protocol-openid-connect-legacy-logout-redirect-uri=true kc.spi-truststore-file-file=/opt/keycloak/conf/ssl/truststore.jks kc.spi-truststore-file-password=TruststorePass2024! EOF

Set up automated certificate renewal

Configure automatic SSL certificate renewal with a cron job.

sudo crontab -e
0 3   * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"

Verify your setup

Test your Keycloak installation and verify all components are working correctly.

# Check service status
sudo systemctl status keycloak
sudo systemctl status postgresql
sudo systemctl status nginx

Check ports are listening

sudo netstat -tlnp | grep -E ':(8080|8443|5432)'

Test database connection

sudo -u postgres psql -d keycloak -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';"

Check logs for errors

sudo tail -f /var/log/keycloak/keycloak.log sudo journalctl -u keycloak --no-pager -l

Test HTTPS access

curl -I https://auth.example.com:8443/health curl -I https://auth.example.com/auth/realms/master

Access the admin console at https://auth.example.com/admin and log in with your admin credentials. You should see the Keycloak admin interface with master realm configuration options.

Common issues

SymptomCauseFix
Service fails to startDatabase connection errorCheck PostgreSQL status and credentials: sudo systemctl status postgresql
SSL certificate errorsIncorrect certificate path or permissionsVerify certificate paths and run sudo chown keycloak:keycloak /opt/keycloak/conf/ssl/*
Out of memory errorsInsufficient JVM heap sizeIncrease Xmx value in keycloak.conf based on available RAM
Clustering not workingFirewall blocking cluster portsEnsure ports 7800 and 57800 are open between cluster nodes
LDAP authentication failsIncorrect bind credentials or DNTest LDAP connection with ldapsearch -H ldap://server -D binddn -W -b basedn
Cannot access admin consoleAdmin user not created properlyRecreate admin user with environment variables during startup
Database migration errorsInsufficient database permissionsGrant full permissions: sudo -u postgres psql -c "ALTER USER keycloak CREATEDB;"

Next steps

Automated install script

Run this to automate the entire setup

#keycloak #identity-provider #sso #oauth2 #openid-connect #keycloak-cluster #enterprise-authentication #ldap-integration #saml #keycloak-ssl

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer