Skip to main content

Web UI Configuration

Configure the Headwind Web UI using environment variables and ConfigMap settings for hot-reload configuration management.

Environment Variables

Configure via the Headwind deployment manifest (deploy/k8s/deployment.yaml):

Authentication

env:
# Authentication mode: none, simple, token, proxy
- name: HEADWIND_UI_AUTH_MODE
value: "none"

# Proxy mode only: header name to read username from
- name: HEADWIND_UI_PROXY_HEADER
value: "X-Forwarded-User"

See Web UI Authentication Guide for detailed authentication configuration.

Notification Integration

env:
# Web UI URL for dashboard links in notifications
- name: HEADWIND_UI_URL
value: "https://headwind.example.com" # or http://localhost:8082

When configured, Slack, Teams, and webhook notifications will include "View in Dashboard" buttons linking to specific UpdateRequests.

ConfigMap Settings

The Web UI supports hot-reload configuration via ConfigMap. Changes are detected automatically without pod restarts.

Creating the ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
name: headwind-config
namespace: headwind-system
data:
config.yaml: |
# Dashboard settings
refresh_interval: 30 # Auto-refresh interval in seconds
max_items_per_page: 20 # Pagination size

# Observability settings
observability:
metricsBackend: "auto" # auto | prometheus | victoriametrics | influxdb | live

prometheus:
enabled: true
url: "http://prometheus-server.monitoring.svc.cluster.local:80"

victoriametrics:
enabled: false
url: "http://victoria-metrics.monitoring.svc.cluster.local:8428"

influxdb:
enabled: false
url: "http://influxdb.monitoring.svc.cluster.local:8086"
org: "headwind" # InfluxDB v2 organization
bucket: "metrics" # InfluxDB v2 bucket
token: "your-api-token" # InfluxDB v2 API token

Mounting the ConfigMap

Update the Headwind deployment to mount the ConfigMap:

apiVersion: apps/v1
kind: Deployment
metadata:
name: headwind
namespace: headwind-system
spec:
template:
spec:
containers:
- name: headwind
volumeMounts:
- name: config
mountPath: /etc/headwind
readOnly: true
volumes:
- name: config
configMap:
name: headwind-config

Apply the changes:

kubectl apply -f deploy/k8s/deployment.yaml

Updating Configuration

Modify the ConfigMap and changes apply automatically:

# Edit ConfigMap
kubectl edit configmap headwind-config -n headwind-system

# Or apply from file
kubectl apply -f headwind-config.yaml

# Configuration reloads automatically (watch logs for confirmation)
kubectl logs -n headwind-system deployment/headwind -f | grep "Configuration reloaded"

No pod restart required - Headwind watches the ConfigMap for changes.

Configuration via Web UI Settings

Access the settings page at /settings in the Web UI to configure:

Observability Settings

  1. Navigate to SettingsObservability / Metrics Storage
  2. Select metrics backend:
    • auto: Automatically detect available backend
    • prometheus: Use Prometheus
    • victoriametrics: Use VictoriaMetrics
    • influxdb: Use InfluxDB
    • live: Use live metrics (no external backend)
  3. Configure backend URLs and options
  4. Click Save Settings

Changes are saved to the ConfigMap and hot-reload automatically.

Dashboard Settings

Configure refresh interval and pagination:

  1. Navigate to SettingsDashboard
  2. Set Refresh Interval (seconds)
  3. Set Max Items Per Page (pagination)
  4. Click Save Settings

Configuration Reference

Dashboard Settings

SettingTypeDefaultDescription
refresh_intervalinteger30Auto-refresh interval in seconds
max_items_per_pageinteger20Number of items per page in dashboard

Observability Settings

SettingTypeDefaultDescription
observability.metricsBackendstringautoBackend selection: auto, prometheus, victoriametrics, influxdb, live
observability.prometheus.enabledbooleantrueEnable Prometheus backend
observability.prometheus.urlstringhttp://prometheus-server.monitoring.svc.cluster.local:80Prometheus URL
observability.victoriametrics.enabledbooleanfalseEnable VictoriaMetrics backend
observability.victoriametrics.urlstringhttp://victoria-metrics.monitoring.svc.cluster.local:8428VictoriaMetrics URL
observability.influxdb.enabledbooleanfalseEnable InfluxDB v2 backend
observability.influxdb.urlstringhttp://influxdb.monitoring.svc.cluster.local:8086InfluxDB v2 URL
observability.influxdb.orgstringheadwindInfluxDB v2 organization
observability.influxdb.bucketstringmetricsInfluxDB v2 bucket name
observability.influxdb.tokenstringheadwind-test-tokenInfluxDB v2 API token

Service Configuration

Configure the Web UI service in deploy/k8s/service.yaml:

ClusterIP (Default)

Internal access only:

apiVersion: v1
kind: Service
metadata:
name: headwind-ui
namespace: headwind-system
spec:
type: ClusterIP
selector:
app: headwind
ports:
- name: ui
port: 8082
targetPort: 8082

Access via port-forward:

kubectl port-forward -n headwind-system svc/headwind-ui 8082:8082

LoadBalancer

External access with cloud provider load balancer:

apiVersion: v1
kind: Service
metadata:
name: headwind-ui
namespace: headwind-system
spec:
type: LoadBalancer
selector:
app: headwind
ports:
- name: ui
port: 80
targetPort: 8082

Get external IP:

kubectl get svc headwind-ui -n headwind-system

NodePort

External access via node port:

apiVersion: v1
kind: Service
metadata:
name: headwind-ui
namespace: headwind-system
spec:
type: NodePort
selector:
app: headwind
ports:
- name: ui
port: 8082
targetPort: 8082
nodePort: 30082 # Optional: specify port (30000-32767)

Access via:

# Get node IP
kubectl get nodes -o wide

# Access at http://<node-ip>:30082

Ingress Configuration

Expose the Web UI via Kubernetes Ingress:

Basic Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: headwind-ui
namespace: headwind-system
spec:
ingressClassName: nginx
rules:
- host: headwind.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: headwind-ui
port:
number: 8082

Ingress with TLS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: headwind-ui
namespace: headwind-system
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- headwind.example.com
secretName: headwind-tls
rules:
- host: headwind.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: headwind-ui
port:
number: 8082

Ingress with Authentication (oauth2-proxy)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: headwind-ui
namespace: headwind-system
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://oauth2-proxy.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://oauth2-proxy.example.com/oauth2/start"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email"
spec:
ingressClassName: nginx
tls:
- hosts:
- headwind.example.com
secretName: headwind-tls
rules:
- host: headwind.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: headwind-ui
port:
number: 8082

With corresponding Headwind configuration:

env:
- name: HEADWIND_UI_AUTH_MODE
value: "proxy"
- name: HEADWIND_UI_PROXY_HEADER
value: "X-Auth-Request-User"
- name: HEADWIND_UI_URL
value: "https://headwind.example.com"

Security Configuration

Read-Only Root Filesystem

The Web UI container runs with a read-only root filesystem:

securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL

Network Policies

Restrict network access to the Web UI:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: headwind-ui
namespace: headwind-system
spec:
podSelector:
matchLabels:
app: headwind
policyTypes:
- Ingress
ingress:
# Allow from ingress controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8082

Resource Limits

Configure resource requests and limits:

resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"

Troubleshooting

Configuration not reloading

Problem: Changes to ConfigMap not detected

Solutions:

  1. Check ConfigMap is mounted correctly:
kubectl exec -n headwind-system deployment/headwind -- ls -la /etc/headwind
  1. Check logs for reload messages:
kubectl logs -n headwind-system deployment/headwind | grep -i config
  1. Restart pod if necessary:
kubectl rollout restart deployment/headwind -n headwind-system

Settings page shows defaults

Problem: ConfigMap settings not loading

Solutions:

  1. Verify ConfigMap exists:
kubectl get configmap headwind-config -n headwind-system -o yaml
  1. Check YAML syntax:
kubectl get configmap headwind-config -n headwind-system -o jsonpath='{.data.config\.yaml}' | yq eval
  1. Check file permissions:
kubectl exec -n headwind-system deployment/headwind -- cat /etc/headwind/config.yaml

Examples

See complete example configurations in the repository:

  • deploy/k8s/configmap.yaml - ConfigMap with all options
  • deploy/k8s/deployment.yaml - Deployment with environment variables
  • deploy/k8s/service.yaml - Service configurations
  • examples/ingress/ - Ingress examples

Next Steps