#!/sbin/openrc-run extra_commands="$extra_commands rebuild" description_rebuild="Rebuild the server image after changing build options." name="Keycloak" description="Open source identity and access management software" : ${cfgfile:="/etc/keycloak/keycloak.conf"} : ${datadir:="/var/lib/keycloak"} : ${setup_admin_user:="yes"} : ${setup_admin_user_password:="generate"} : ${command_user:="keycloak:keycloak"} : ${healthcheck_delay:=90} : ${healthcheck_timer:=30} : ${healthcheck_url="https://127.0.0.1:9000/health/live"} : ${retry="TERM/15/KILL/5"} command="/usr/bin/kc" command_args="-cf $cfgfile start ${command_args-"--optimized"}" command_background="yes" pidfile="/run/$RC_SVCNAME.pid" directory="$datadir" required_files="$cfgfile" # Alpine-specific variables for kc.sh. export KCSH_CONFIG_DIR="${cfgfile%/*}" export KCSH_HOME_DIR="$datadir" depend() { need net after firewall } start_pre() { local first_start=false export JAVA_OPTS_APPEND="$java_opts" # Note: Quarkus rotates logs after 10 MiB by default. export QUARKUS_LOG_FILE_ROTATION_FILE_SUFFIX="-yyyyMMdd" export QUARKUS_LOG_FILE_ROTATION_ROTATE_ON_BOOT=false # The second condition is for backward compatibility with <24.0.5-r1. if ! [ -e "$datadir"/version.txt ] && ! [ -d "$datadir"/build/quarkus ]; then first_start=true fi if [ -f "$datadir"/build/quarkus/build-system.properties ]; then # This directory was used before 24.0.5-r1. ewarn "Removing obsolete directory $datadir/build" rm -rf "$datadir"/build fi # After installing/upgrading Keycloak, we have to rebuild... if ! cmp "$datadir"/version.txt /usr/share/keycloak/version.txt >/dev/null 2>&1; then rebuild fi if [ "$(conf_get 'health-enabled')" != 'true' ]; then healthcheck_url="" fi local hostname="$(conf_get 'hostname' | sed -E 's|^https?://||i; s|/.*||')" if [ "$hostname" = 'change-me' ]; then ewarn 'Change "hostname" in $cfgfile to the full domain name of the server!' hostname="$(hostname -f)" fi local certfile="$(conf_get 'https-certificate-file')" local keyfile="$(conf_get 'https-certificate-key-file')" if [ "$certfile" ] && ! [ -e "$certfile" ] && ! [ -e "$keyfile" ]; then if command -v openssl >/dev/null; then einfo "Generating self-signed certificate and private key..." gen_cert "$hostname" "$certfile" "$keyfile" else eerror "$certfile or $keyfile does not exist!" return 1 fi fi # KEYCLOAK_ADMIN_PASSWORD is deprecated since Keycloak 26.0.0. if $first_start \ && yesno "$setup_admin_user" \ && [ -z "${KC_BOOTSTRAP_ADMIN_PASSWORD-}" ] \ && [ -z "${KEYCLOAK_ADMIN_PASSWORD-}" ] then if [ "$setup_admin_user_password" = 'generate' ]; then setup_admin_user_password="$(gen_pass)" ewarn "Initial admin user \"admin\" will be created with password: $setup_admin_user_password" else ewarn 'Initial admin user "admin" will be created' fi export KC_BOOTSTRAP_ADMIN_USERNAME="admin" export KC_BOOTSTRAP_ADMIN_PASSWORD="$setup_admin_user_password" fi } healthcheck() { [ -n "$healthcheck_url" ] || return 0 # Note: We don't check certificate because Keycloak may run with self-signed # certificate behind a proxy that re-encrypts traffic. if command -v curl >/dev/null; then curl -fq --max-time 10 --insecure --head "$healthcheck_url" >/dev/null 2>&1 || return 1 elif command -v wget >/dev/null; then wget -q -T 10 --no-check-certificate -O - "$healthcheck_url" >/dev/null 2>&1 || return 1 fi } rebuild() { ebegin "Rebuilding $name" echo '' checkpath -d -o "$command_user" "$datadir" || return 1 su "${command_user%:*}" -s /bin/sh -c "$command build" } gen_cert() { openssl req -x509 \ -newkey ec \ -pkeyopt ec_paramgen_curve:prime256v1 \ -nodes \ -days 7300 \ -subj "/CN=$1" \ -out "$2" \ -keyout "$3" chown "$command_user" "$certfile" "$keyfile" } gen_pass() { head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12 } conf_get() { sed -En "s/^$1=(\S+).*/\1/p" "$cfgfile" }