Install standalone Keycloak server

The standalone Keycloak server is only supported at a development environment. In a production environment, the service should be redundant, and the Keycloak application can form a cluster in various ways. But in case of cluster, the data should be stored in an external database, which, in turn, must be redundant too. In addition, incoming requests to this redundant application cluster must go through a load balancer. The project becomes too complex and must include at least three nodes to implement this redundancy.

Another option is to install all components on the kubernetes platform. This is probably the preferred option if you have a good kubernetes support team.

From the other side, you usually already have an existing and redundant virtualization platform, that can restart a virtual machine in a minute in case of the physical hardware failure. I cannot decide about downtime for companies giving external service, but this is usually acceptable for any company's internal use.

Standalone installation simplifies a lot. When the external database is not needed, the internal database becomes files based and backup becomes much easier. For example, it could be a daily snapshot of the VM. When all components are on the same server, internal traffic can be left unencrypted, which also simplifies setup and maintenance.

This approach is to install a production server in standalone mode.

Preparing Server

A minimal installation of SUSE SLE 15 SP4 was installed on a virtual machine with 2 processors and 4G of memory. Left enough space in the /opt directory to store the installation itself and live data. Add some programs for comfortable work:

root@kc:~ # zypper in vim bash-completion rsync rsyslog
Bold font indicates the command that you are typing, the rest is the output of the command.

It is important to set up a fixed IP address and DNS name for a server. In this demo it is kc.mydomain.com. Please create a server SSL certificate for this name, IP and FQDN. Save the certificate and private key for future use.

The local CA must be known and trusted. To do this, place the CA certificate in the appropriate location and run the command:

root@kc:~ # cp -v ca.crt /etc/pki/trust/anchors/
'ca.crt' -> '/etc/pki/trust/anchors/ca.crt'
root@kc:~ # update-ca-certificates

Install Keycloak

Download the archive from the project site. Open the archive in /opt. The referenced version is "20.0.2" , which is current for keycloak at the time of writing.

root@kc:~ # tar -C /opt -xf keycloak-20.0.2.tar.gz
root@kc:~ # ln -s keycloak-20.0.2 /opt/keycloak
root@kc:~ # ll /opt
total 4
lrwxrwxrwx 1 root root   15 Jan  3 14:56 keycloak -> keycloak-20.0.2
drwxr-xr-x 7 root root 4096 Jan  3 14:49 keycloak-20.0.2

Keycloak is a Java application, so Java must be installed. Version 11 is recommended by the manufacturer.

root@kc:~ # zypper in java-11-openjdk
 ..
root@kc:~ # java --version
openjdk 11.0.17 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+0-suse-150000.3.86.2-x8664)
OpenJDK 64-Bit Server VM (build 11.0.17+0-suse-150000.3.86.2-x8664, mixed mode)

The next step is to fix the KeyCloak configuration file to suit our needs. Here is a working example file:

# /opt/keycloak/conf/keycloak.conf
#
# Data in files
db=dev-file
# No distributed cache
cache=local
# this is my hostname for redirects
hostname=kc.mydomain.com
hostname-strict=false
# listen to HTTP on 127.0.0.1:8008
hostname-strict-https=false
http-enabled=true
http-host=127.0.0.1
http-port=8008
# hint KeyCloak that SSL terminated externally by proxy
proxy=edge

You have to fix your hostname=.

Now we need to create a service user, since we don't want the service to run as root:

root@kc:~ # groupadd --system keycloak
root@kc:~ # useradd --system -g keycloak keycloak
root@kc:~ # id keycloak
uid=475(keycloak) gid=474(keycloak) groups=474(keycloak)
root@kc:~ # chown -R keycloak:keycloak /opt/keycloak/*

Then create a systemd Unit file for the keycloak service.

# /etc/systemd/system/keycloak.service
[Unit]
Description=Keycloak local service
After=network-online.target
Wants=network-online.target
 
[Service]
Type=simple
Restart=always
User=keycloak
Group=keycloak
#Environment="KEYCLOAK_ADMIN=admin"
#Environment="KEYCLOAK_ADMIN_PASSWORD=adminpassword"
ExecStart=!/opt/keycloak/bin/kc.sh start
ExecStop=/usr/bin/killall -u keycloak
 
[Install]
WantedBy=multi-user.target

On very first run, uncomment and set the initial administrator name and password. Force systemd to reread the configuration and start the service.

root@kc:~ # systemctl daemon-reload
root@kc:~ # systemctl enable --now keycloak
Created symlink /etc/systemd/system/multi-user.target.wants/keycloak.service → /etc/systemd/system/keycloak.service.
root@kc:~ # journalctl -u keycloak.service

Install haproxy

Haproxy will terminate the SSL and forward the requests to the backend service. Let's install and configure haproxy.

root@kc:~ # zypper in haproxy
 ..
root@kc:~ # cat /etc/haproxy/haproxy.cfg
 ..
frontend main
    bind *:443 ssl crt /etc/haproxy/certs
    # Add X-Headers necessary for HTTPS
    http-request set-header X-Forwarded-Host %[req.hdr(Host)]
    http-request set-header X-Forwarded-Proto https
    option forwardfor

    default_backend kc

backend kc
    balance source
    mode http
    http-request set-header X-Forwarded-Proto https
    server k1 127.0.0.1:8008 check

The /etc/haproxy/certs directory should include combined sertificates. Here is an example of creation such file:

root@kc:~ # mkdir /etc/haproxy/certs
root@kc:~ # cat kc.mydomain.com.key kc.mydomain.com.crt > /etc/haproxy/certs/kc.mydomain.com.pem

Files .key and .crt are parts of server SSL sertificates you had obtained above.

Start the haproxy service.

root@kc:~ # systemctl enable --now haproxy
Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.

Reset admin password

Log in with the initial admin user and the password set in the systemd Unit file. Go to "Users", click on admin user and "Reset password" in the "Credentials" tab. When resetting, turn off the "Temporary" switch to make the password permanent.

After password reset, edit the systemd Unit file again and remove the admin user and password lines. Then reload systemd and restart keycloak.

root@kc:~ # vi /etc/systemd/system/keycloak.service
root@kc:~ # systemctl daemon-reload
root@kc:~ # systemctl restart keycloak

Updated on Wed Jan 4 12:57:54 IST 2023 More documentations here