A simple static dashboard listing Kubernetes clusters and related apps, with a searchable card view. Built with Tailwind CSS and Stimulus.
  • JavaScript 63.4%
  • HTML 32.1%
  • Dockerfile 4.5%
Find a file
2026-06-13 12:09:47 +02:00
controllers Move data to separate folder 2026-06-13 11:20:48 +02:00
data Move data to separate folder 2026-06-13 11:20:48 +02:00
openshift Add building on OpenShift via BuildConfig or Tekton 2026-06-13 12:09:47 +02:00
.gitignore Initial commit 2026-06-13 10:53:01 +02:00
application.js Initial commit 2026-06-13 10:53:01 +02:00
Containerfile Move data to separate folder 2026-06-13 11:20:48 +02:00
index.html Initial commit 2026-06-13 10:53:01 +02:00
LICENSE Initial commit 2026-06-13 10:53:01 +02:00
README.md Add building on OpenShift via BuildConfig or Tekton 2026-06-13 12:09:47 +02:00

Clusters Dashboard

A simple static dashboard listing Kubernetes clusters and related apps (e.g. ArgoCD, Grafana, Vault), with a searchable card view. Built with Tailwind CSS and Stimulus.

Features

  • Card per cluster with name, environment, region, version, and a link to its console
  • Search bar that filters clusters by any of the above fields
  • Separate "Apps" section for general tools (ArgoCD, Grafana, etc.)
  • Data-driven via data/clusters.json and data/apps.json — no backend required

Local development

Because the dashboard fetches data/clusters.json and data/apps.json via JavaScript, it must be served over HTTP (not opened directly as a file:// URL).

python3 -m http.server

Then open http://localhost:8000.

Configuration

  • data/clusters.json — list of clusters. Each entry supports name, consoleUrl, environment, region, and version.
  • data/apps.json — list of additional apps/tools. Each entry supports name, url, and description.

Container image

Build with Podman or Docker using the provided Containerfile:

podman build -t clusters-dashboard -f Containerfile .
podman run -p 8080:8080 clusters-dashboard

The image is based on registry.access.redhat.com/ubi9/nginx-122, which runs as a non-root, arbitrary UID — compatible with OpenShift's restricted SCC.

CI/CD options

The base Deployment (openshift/deployment.yaml) references the internal ImageStream: image-registry.openshift-image-registry.svc:5000/<namespace>/clusters-dashboard:latest (replace <namespace> with your project). Two ways to build and push that image tag are supported.

Option A: In-cluster Build + ImageStream

oc apply -k openshift/build/
oc start-build clusters-dashboard --follow

openshift/build/ contains an ImageStream and BuildConfig that build the image directly on OpenShift from Containerfile (Docker strategy), plus a kustomize overlay that layers on top of openshift/ (resources: [../, imagestream.yaml, buildconfig.yaml]) and patches the Deployment via deployment-imagestream-patch.yaml to add the image.openshift.io/triggers annotation — so a successful Build that updates the clusters-dashboard:latest ImageStreamTag automatically rolls out the Deployment.

Update spec.source.git.uri in openshift/build/buildconfig.yaml to point at your repository. The BuildConfig has ConfigChange and ImageChange triggers, so manual oc start-build is mainly needed for the first run or after pushing new commits (unless a webhook trigger is added).

Option B: Tekton Pipeline

Requires the OpenShift Pipelines operator. openshift/tekton/ contains a Pipeline (clusters-dashboard-build) that clones the repo and builds/pushes the image with buildah using the Containerfile.

oc apply -k openshift/tekton/

Trigger a run, either via tkn:

tkn pipeline start clusters-dashboard-build \
  -p git-url=https://opencommit.eu/johan/clusters-dashboard.git \
  -p git-revision=main \
  -p image=image-registry.openshift-image-registry.svc:5000/<namespace>/clusters-dashboard:latest \
  -w name=shared-workspace,volumeClaimTemplateFile=-

or by editing and applying the example openshift/tekton/pipelinerun.yaml (oc create -f openshift/tekton/pipelinerun.yaml).

Combine with the Option A overlay so the image.openshift.io/triggers annotation picks up the new image automatically. Add a Tekton Trigger/EventListener if you want builds to fire on git push webhooks.

To push to an external registry (e.g. quay.io) instead, create a docker-registry secret with those credentials and add it back as a dockerconfig workspace binding in the PipelineRun (the Pipeline already declares this workspace as optional).

Deploying to OpenShift

Manifests live under openshift/ and are managed with Kustomize:

oc apply -k openshift/

This creates a Deployment, Service, and Route for the dashboard.

Overriding clusters.json / apps.json per environment

The Deployment mounts a ConfigMap named clusters-dashboard-data over the data/ directory, overriding the clusters.json and apps.json baked into the image. This lets you keep real cluster/app data (internal hostnames, etc.) out of this repo.

See openshift/configmap.example.yaml for the expected shape. Copy it, fill in real values, and apply it before (or alongside) the other resources:

oc apply -f configmap.yaml
oc apply -k openshift/

Because the ConfigMap is mounted as a directory (not via subPath), the kubelet periodically syncs changes to the mounted files (typically within ~1 minute), and a browser refresh picks up the new data — no pod restart required.

Note: although the volume is marked optional: true, if the ConfigMap doesn't exist the mount becomes an empty directory and shadows the image's built-in data/ files, so the dashboard will show no data until the ConfigMap is created. If you don't need per-environment overrides, remove the volumes and volumeMounts sections from deployment.yaml and the image's built-in JSON files will be used.

License

MIT — see LICENSE.