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.
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 rsyslogBold 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
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
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.
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