This guide shows how to install Keycloak behind NGINX with SSL termination using Let’s Encrypt, and an existing MariaDB server. Keycloak will run as a non-system user and be configured for production.
Prerequisites
- An Ubuntu 24.04 server
- A public domain name pointing to your server (e.g.,
keycloak.maksonlee.com
) - Existing MariaDB server
- Existing NGINX installation
- Ports 80 and 443 open
- Create Keycloak Database and User in MariaDB
sudo mysql -u root -p
Inside MariaDB shell:
CREATE DATABASE keycloak;
CREATE USER 'keycloak'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'localhost';
FLUSH PRIVILEGES;
EXIT;
- Install Java 21
sudo apt update
sudo apt install openjdk-21-jdk -y
java -version
- Download and Install Keycloak
wget https://github.com/keycloak/keycloak/releases/download/26.2.0/keycloak-26.2.0.tar.gz
tar -xvzf keycloak-26.2.0.tar.gz
sudo mv keycloak-26.2.0 /opt/keycloak
sudo useradd -m keycloak
sudo chown -R keycloak:keycloak /opt/keycloak
- Add MariaDB JDBC Driver
sudo wget https://downloads.mariadb.com/Connectors/java/connector-java-3.5.3/mariadb-java-client-3.5.3.jar -O /opt/keycloak/providers/mariadb.jar
sudo chown keycloak:keycloak /opt/keycloak/providers/mariadb.jar
- Configure Keycloak
sudo su - keycloak
Edit /opt/keycloak/conf/keycloak.conf
:
db=mariadb
db-username=keycloak
db-password=your_secure_password
db-url=jdbc:mariadb://localhost:3306/keycloak
hostname=keycloak.maksonlee.com
http-enabled=true
http-host=127.0.0.1
proxy-headers=xforwarded
- Build Keycloak
cd /opt/keycloak
bin/kc.sh build
exit
- Add NGINX Config (No SSL Yet)
Before running Certbot, create a simple config:
server {
listen 80;
server_name keycloak.maksonlee.com;
location / {
proxy_pass http://127.0.0.1:8080;
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 http;
}
}
Save as:
/etc/nginx/sites-enabled/keycloak
Then reload NGINX:
sudo nginx -t && sudo systemctl reload nginx
- Get SSL Certificate via Certbot
sudo certbot --nginx -d keycloak.maksonlee.com
Certbot will automatically update the NGINX config with SSL.
- Final NGINX Config (With SSL + Headers)
Verify your final config looks like this:
server {
server_name keycloak.maksonlee.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/keycloak.maksonlee.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/keycloak.maksonlee.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:8080;
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 https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
server {
listen 80;
server_name keycloak.maksonlee.com;
return 301 https://$host$request_uri;
}
- Start Keycloak with Temporary Admin User
sudo su - keycloak
export KC_BOOTSTRAP_ADMIN_USERNAME=admin
export KC_BOOTSTRAP_ADMIN_PASSWORD=admin
export JAVA_OPTS="-Xms128m -Xmx128m"
cd /opt/keycloak
bin/kc.sh start
You can now visit:
https://keycloak.maksonlee.com
Login with the credentials above. You’ll see a warning to create a permanent admin user.
- Run Keycloak as a Systemd Service
Create a unit file:
sudo vi /etc/systemd/system/keycloak.service
Paste the following:
[Unit]
Description=Keycloak Server
After=network.target
[Service]
User=keycloak
Group=keycloak
WorkingDirectory=/opt/keycloak
ExecStart=/opt/keycloak/bin/kc.sh start --http-host=127.0.0.1
Restart=always
Environment=JAVA_OPTS=-Xms128m -Xmx128m
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl enable keycloak
sudo systemctl start keycloak
Your Keycloak is now running securely behind NGINX with SSL termination and using MariaDB as backend storage.