Files
mg4/k8s/grafana.yaml
T
nilsandClaude Opus 5.5 5473ab1c2b Dashboards in Grafana; clean up after the Next.js app
- k8s/grafana.yaml: Grafana 13.2.3 with a 1Gi PVC, sign-up and
  anonymous access off. The InfluxDB datasource (URL and token from the
  environment) and three dashboards — Live, Consumption, Charging — are
  provisioned from k8s/grafana/ via kustomize-generated ConfigMaps.
- server.yaml for the Go server (port 8080, UID 65532, smaller limits),
  image tag 2.0.0. The NetworkPolicy now admits Grafana to InfluxDB.
- ingress.yaml: IngressRoutes for car.stinnesbeck.com and Grafana
  (placeholder host car-grafana.stinnesbeck.com) with tls: {}, using
  Traefik's default certificate; the cert-manager Certificate is gone.
- secrets.example.yaml: drops the dashboard secrets, adds grafana-admin.
- AGENTS.md loses its Next.js block; SPECS.md describes the new setup.

The removal of web/ (the Next.js app) and of the stale .next/ cache
upstream had committed already landed in 51e6f6f, which was staged
together with the Go server by mistake.

Checked end to end in podman (Go server + InfluxDB 2.7.12 + Grafana
13.2.3): all 25 dashboard queries return the expected data, and the
dashboards were rendered with headless Chromium. Manifests validated
offline with kustomize and kubeconform. Nothing applied to a cluster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
2026-10-17 15:18:09 +02:00

138 lines
3.8 KiB
YAML

# Grafana for the dashboards. The InfluxDB datasource and the three MG4 dashboards are
# provisioned from k8s/grafana/ (ConfigMaps generated by kustomization.yaml); the dashboards
# are read-only in the UI — change the JSON in git instead.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-data
namespace: mg4
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: mg4
spec:
accessModes: ["ReadWriteOnce"]
# No storageClassName: the cluster's default class is used.
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: mg4
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: mg4
spec:
replicas: 1
strategy:
type: Recreate # the SQLite database on the volume allows one writer
selector:
matchLabels:
app.kubernetes.io/name: grafana
template:
metadata:
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: mg4
spec:
securityContext:
runAsNonRoot: true
runAsUser: 472
runAsGroup: 472
fsGroup: 472
seccompProfile:
type: RuntimeDefault
containers:
- name: grafana
image: docker.io/grafana/grafana:13.2.3
ports:
- name: http
containerPort: 3000
env:
- name: GF_SERVER_ROOT_URL
value: https://car-grafana.stinnesbeck.com
- name: GF_SECURITY_ADMIN_USER
value: admin
- name: GF_SECURITY_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-admin
key: admin-password
- name: GF_USERS_ALLOW_SIGN_UP
value: "false"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "false"
- name: GF_ANALYTICS_REPORTING_ENABLED
value: "false"
- name: GF_ANALYTICS_CHECK_FOR_UPDATES
value: "false"
# Read by datasources.yaml.
- name: INFLUX_URL
value: http://influxdb.mg4.svc:8086
- name: INFLUX_TOKEN
valueFrom:
secretKeyRef:
name: influxdb-auth
key: admin-token
volumeMounts:
- name: data
mountPath: /var/lib/grafana
- name: datasources
mountPath: /etc/grafana/provisioning/datasources
- name: dashboard-provider
mountPath: /etc/grafana/provisioning/dashboards
- name: dashboards
mountPath: /var/lib/grafana/dashboards/mg4
readinessProbe:
httpGet:
path: /api/health
port: http
periodSeconds: 10
livenessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 30
periodSeconds: 30
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
volumes:
- name: data
persistentVolumeClaim:
claimName: grafana-data
- name: datasources
configMap:
name: grafana-datasources
- name: dashboard-provider
configMap:
name: grafana-dashboard-provider
- name: dashboards
configMap:
name: grafana-dashboards
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: mg4
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/part-of: mg4
spec:
selector:
app.kubernetes.io/name: grafana
ports:
- name: http
port: 80
targetPort: http