Limited Time Offer!
For Less Than the Cost of a Starbucks Coffee, Access All DevOpsSchool Videos on YouTube Unlimitedly.
Master DevOps, SRE, DevSecOps Skills!
1. Background
Youโre running:
- Keycloak 26.3.3 (Quarkus-based)
- LAMPP (XAMPP for Linux 8.2.4) stack at
/opt/lampp - MariaDB managed by LAMPP (
/opt/lampp/sbin/mysqld) - Systemd-based service for permanent Keycloak startup
Goal:
Run Keycloak as a systemd service using MariaDB from LAMPP, with production settings, automatic startup, and full connectivity.
2. Common Issues Encountered
Issue 1 โ Keycloak Fails Under Systemd
keycloak.service: Main process exited, code=exited, status=1/FAILURE
Cause: Running as keycloak user but DB authentication failed due to incorrect socket or ENV overrides.
Issue 2 โ โAccess denied for user ‘root’@’localhost’โ
Cause:
LAMPP uses UNIX socket authentication for root@localhost, while Keycloak (running as keycloak user) doesnโt have permission to use that socket.
Issue 3 โ โSocket fail to connect to 127.0.0.1. Connection refusedโ
Cause:
LAMPP MySQL wasnโt listening on TCP (only socket). Hence, Keycloakโs JDBC TCP URL (127.0.0.1:3306) couldnโt connect.
Issue 4 โ kc.db-url still showing (ENV) source
Cause:
Old shell exports like KC_DB_URL, KC_DB_USERNAME, etc., in rootโs environment were overriding keycloak.conf.
3. Step-by-Step Solution
Step 1 โ Clean up any leftover ENV variables
Run as root:
unset KC_DB_URL KC_DB KC_DB_USERNAME KC_DB_PASSWORD KC_HOSTNAME KC_HTTP_ENABLED
Then verify:
env | egrep '^KC_|^kc\.' || echo "no KC_* env"
Step 2 โ Fix the Keycloak DB config
Edit:
sudo nano /opt/auth.myhospitalnow.com/conf/keycloak.conf
Use this:
# ---------- DB ----------
db=mariadb
db-username=root
db-password=UW7k(rDc3t&cUIu7i#G0&c$B
db-url=jdbc:mariadb://127.0.0.1:3306/keycloak_db
db-pool-initial-size=5
db-pool-min-idle=5
db-pool-max-size=25
db-pool-prefill=true
# ---------- HTTP ----------
http-enabled=true
http-port=8080
# ---------- HOSTNAME ----------
hostname=auth.myhospitalnow.com
hostname-strict=false
hostname-strict-backchannel=false
proxy-headers=xforwarded
proxy=none
# ---------- CACHE ----------
cache=local
health-enabled=true
metrics-enabled=true
Key fixes:
- Removed
localSocket=/opt/lampp/var/mysql/mysql.sock- Switched to TCP:
jdbc:mariadb://127.0.0.1:3306/keycloak_db- No quotes around passwords
Step 3 โ Enable TCP networking in LAMPP MySQL
Edit /opt/lampp/etc/my.cnf:
sudo nano /opt/lampp/etc/my.cnf
Ensure:
[mysqld]
port=3306
bind-address=127.0.0.1
# Comment out if found:
# skip-networking
# skip-bind-address
Restart MySQL:
sudo /opt/lampp/lampp restartmysql
Confirm itโs listening:
sudo ss -ltnp | grep 3306
Step 4 โ Allow TCP login for root
sudo /opt/lampp/bin/mysql -u root -p
Inside MySQL:
CREATE DATABASE IF NOT EXISTS keycloak_db;
CREATE USER IF NOT EXISTS 'root'@'127.0.0.1' IDENTIFIED BY 'UW7k(rDc3t&cUIu7i#G0&c$B';
GRANT ALL PRIVILEGES ON keycloak_db.* TO 'root'@'127.0.0.1';
FLUSH PRIVILEGES;
Then test:
sudo -u keycloak /opt/lampp/bin/mysql -h 127.0.0.1 -uroot -p keycloak_db -e "SELECT 1;"
Step 5 โ Rebuild Keycloak runtime
/opt/auth.myhospitalnow.com/bin/kc.sh build
Check config sources:
/opt/auth.myhospitalnow.com/bin/kc.sh show-config | egrep '^(kc\.db|kc\.db-|kc\.db-url)'
All should now say (keycloak.conf)
Step 6 โ Create clean systemd unit
Create:
sudo nano /etc/systemd/system/keycloak.service
Add:
[Unit]
Description=Keycloak Server
After=network.target mariadb.service
Wants=network-online.target
[Service]
User=keycloak
Group=keycloak
WorkingDirectory=/opt/auth.myhospitalnow.com
Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
Environment=PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=JAVA_OPTS=-Xms512m -Xmx2048m
ExecStartPre=/bin/sh -c 'for i in $(seq 1 30); do nc -z 127.0.0.1 3306 && exit 0; sleep 1; done; exit 1'
ExecStart=/opt/auth.myhospitalnow.com/bin/kc.sh start --optimized
ExecStop=/opt/auth.myhospitalnow.com/bin/kc.sh stop
Restart=always
RestartSec=5
TimeoutStartSec=120
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Apply changes:
sudo systemctl daemon-reload
sudo systemctl enable keycloak
Step 7 โ Fix ownership and permissions
sudo useradd -r -s /usr/sbin/nologin keycloak 2>/dev/null || true
sudo chown -R keycloak:keycloak /opt/auth.myhospitalnow.com
sudo chmod +x /opt/auth.myhospitalnow.com/bin/kc.sh
Step 8 โ Test Run
Run manually first:
sudo -u keycloak /opt/auth.myhospitalnow.com/bin/kc.sh start --optimized
If it starts fine, enable permanent startup:
sudo systemctl restart keycloak
sudo systemctl status keycloak
Should show Active (running).
4. Verification Checklist
| Check | Command | Expected Output |
|---|---|---|
| MariaDB listening on TCP | `sudo ss -ltnp | grep 3306` |
| Keycloak DB connectivity | sudo -u keycloak /opt/lampp/bin/mysql -h 127.0.0.1 -uroot -p keycloak_db -e "SELECT 1;" | 1 |
| Keycloak DB source | kc.sh show-config | (keycloak.conf) |
| Keycloak systemd status | sudo systemctl status keycloak | Active (running) |
5. Troubleshooting Summary
| Error | Root Cause | Fix |
|---|---|---|
| Access denied for user ‘root’@’localhost’ | Using UNIX socket auth | Created root@127.0.0.1 with password |
| Connection refused to 127.0.0.1 | LAMPP disabled TCP | Enabled port=3306 and bind-address=127.0.0.1 |
| kc.db-url from (ENV) | Old shell exports | unset KC_* and rebuild |
| Starts manually but not via systemd | Java PATH missing | Added JAVA_HOME and PATH in unit |
| Service fails at boot | DB not ready | Added ExecStartPre with port-wait loop |
๐ง 6. Bonus Tips
- For HTTPS later, add:
https-certificate-file=/opt/auth.myhospitalnow.com/conf/server.crt.pem https-certificate-key-file=/opt/auth.myhospitalnow.com/conf/server.key.pem - Logs live in:
/opt/auth.myhospitalnow.com/data/log/ journalctl -u keycloak -f - To test admin login:
http://auth.myhospitalnow.com:8080

Leave a Reply