logo
Blog Image

Building a Production-Ready GeoServer Stack with Keycloak, Loki & Prometheus

Posted on May 4, 2026

1 min read

By Megha K. Shinde

Introduction

GeoServer is powerful for serving geospatial data, but in real-world deployments, it lacks a few critical capabilities out of the box:

  • Centralized authentication (SSO)
  • Log aggregation and monitoring
  • Observability for debugging and performance

In this blog, we’ll build a production-ready GeoServer stack using:

  • GeoServer
  • Keycloak
  • Loki
  • Prometheus
  • Grafana

Architecture Overview

Flow

  1. User accesses GeoServer
  2. Redirected to Keycloak (SSO login)
  3. Keycloak authenticates and returns token
  4. GeoServer maps roles
  5. Logs → Loki via Promtail
  6. Metrics → Prometheus
  7. Visualization → Grafana

Project Structure

 

docker-compose.yml
geoserver/
keycloak/
loki/
promtail/
prometheus/
grafana/
scripts/

 

🌍 GeoServer Setup

GeoServer acts as the core geospatial engine:

  • WMS, WFS, WCS services
  • Admin UI
  • Plugin-based extensions

🔐 Keycloak Integration (SSO)

 

Keycloak provides:

  • Centralized login
  • Role-based access control
  • OIDC integration

⚙️ Setup Highlights:

  • Realm: april-task
  • Client: geoserver-client
  • Roles:
    • geoserverAdmin
    • geoserverUser

Critical Learning: Internal vs External URLs

This was one of the biggest issues:

ContextURL
Browserhttp://localhost:8081
Containerhttp://keycloak:8080

❗ If you use localhost inside Docker → OIDC will break

 

ROLE MAPPING

geoserverAdmin=ROLE_ADMINISTRATOR
geoserverUser=ROLE_AUTHENTICATED

GeoServer → Security → Authentication → OIDC config

 

 

Logging with Loki

 

Loki + Promtail helps collect logs from:

  • GeoServer logs
  • Tomcat logs
  • Audit logs
Implementing the monitoring stack using Node Exporter, Prometheus, and Grafana using Docker-Compose. | by NetOpsChic | Medium

 

 

🚨 Issue Faced

Dashboard was empty 

Because only logs existed:

  • geoserver
  • geoserver_access

But dashboard expected:

  • geoserver_audit

👉 This mismatch caused confusion


✅ Fix

Enable GeoServer monitoring:

 

audit.enabled=true
micrometer.enabled=true

 

After fix:

  • geoserver_audit.log created ✔
  • Loki started receiving correct logs ✔

     

Troubleshooting Section (MOST IMPORTANT )

Issue 1: Keycloak not redirecting

  • Cause: Wrong redirect URI
  • Fix: Correct OIDC configuration

Issue 2: File download instead of login

  • Cause: Misconfigured authentication filter
  • Fix: Fix filter chain

Issue 3: Empty Grafana dashboard

  • Cause: Missing audit logs
  • Fix: Enable monitoring

Issue 4: Admin role not working

  • Cause: Username conflict (admin)
  • Fix:
    • Use different user (e.g., megha-admin)
    • Keep default admin as fallback

🧠 Key Learnings

  • Docker networking matters (very important)
  • Authentication ≠ Authorization
  • Observability requires proper instrumentation
  • Always keep fallback admin access

Final Result

✔ GeoServer with persistent config
✔ Keycloak SSO login
✔ Role-based access
✔ Logs in Loki
✔ Metrics in Prometheus
✔ Dashboards in Grafana


Future Improvements

  • Combine all services into one clean docker-compose.yml
  • Add HTTPS (production ready)
  • Add Nginx reverse proxy
  • Scale GeoServer (HA setup)

🎯 Conclusion

GeoServer alone is not enough for modern systems.

With Keycloak, Loki, and Prometheus, it becomes:

👉 Secure
👉 Observable
👉 Production-ready

 

Image

Unlock Exclusive Content and Stay updated.

Subscribe today!

Interesting content are in store for you.

What are you interested to know more about?