Tested on Keycloak 26.0.7

Postgres Setup Link to heading

Install postgresql with your package manager, for e.g. sudo apt install postgresql (postgres user will be created in the process)

sudo systemctl start postgresql sudo systemctl enable postgresql

switch to the postgres user: sudo -u postgres -i

find out where the config file is located: psql -U postgres -c 'SHOW config_file'

pg_hba.conf config: host all all 0.0.0.0/0 md5

postgresql.conf config: listen_addresses = '*'

Create User and Database (in the shell and NOT with psql): createuser keycloak createdb keycloak

Access the postgres shell with psql, provide privileges to the postgres user “keycloak”: alter user keycloak with encrypted password 'password'; grant all privileges on database keycloak to keycloak;

Troubleshoot Link to heading

“ERROR: permission denied for schema public”: Link to heading

\c keycloak postgres (this line connects to keycloak database as user postgres) GRANT ALL ON SCHEMA public TO keycloak; exit or ctrl+d systemctl restart postgresql

No database cluster initialized: Link to heading

initdb -D /var/lib/postgres/data

Keycloak + Config Setup Link to heading

Download Keycloak zip file: https://www.keycloak.org/downloads

Environment variable for temporary admin user does not work, use this command to run the setup: bin/kc.sh bootstrap-admin user

Setup domain name + https with certbot. Copy the cert generated by certbot to the keycloak home folder and enable read permission.

keycloak config located at: <keycloak-folder>/conf/keycloak.conf

update the keycloak config (showing the relevant parts):

db=postgres
db-username=keycloak
db-password=password
db-url=jdbc:postgresql://0.0.0.0:5432/keycloak # keycloak refers to the database name

# The file path to a server certificate or certificate chain in PEM format.
https-certificate-file=some-path/fullchain.pem

# The file path to a private key in PEM format.
https-certificate-key-file=some-path/privkey.pem

# Hostname for the Keycloak server.
hostname=your-domain-name.com

# https-port=443
# hostname-strict=false
# http-enabled=true # To enable the use of HTTP in production

Run with bin/kc.sh start

Nginx Reverse Proxy Setup Link to heading

server {
	server_name  domain-name.com;

	listen 443 ssl; # managed by Certbot
	ssl_certificate /etc/letsencrypt/live/[domain-name]/fullchain.pem; # managed by Certbot
	ssl_certificate_key /etc/letsencrypt/live/[domain-name]/privkey.pem; # managed by Certbot
	include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
	ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

	location / {
		proxy_pass https://localhost:8443;
		proxy_http_version 1.1;
		proxy_set_header   Upgrade $http_upgrade;
		proxy_set_header   Connection keep-alive;
		proxy_set_header   Host $host;
		proxy_set_header   Accept-Encoding *;
		proxy_cache_bypass $http_upgrade;
		proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header   X-Forwarded-Proto $scheme;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_buffer_size   256k;
		proxy_buffers   4 512k;
		proxy_busy_buffers_size   512k;
		proxy_hide_header       X-Content-Type-Options;
	}
}

Ref: Unable to preload CSS: https://github.com/keycloak/keycloak/issues/12719

Troubleshoot Link to heading

CORS issue, the following can be added in nginx too to aid in troubleshooting:

add_header Access-Control-Allow-Origin '*' always;
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
if ($request_method = 'OPTIONS') {
	return 204;
}

Client Setup Link to heading

URL for your app’s authentication: https://domain-name/realms/[your realm]