Skip to main content

Helm Chart Configuration Guide

This guide explains how to configure GeoPulse when deployed to Kubernetes using the Helm chart. It covers both built-in configuration options and advanced customization techniques.

Overview

The GeoPulse Helm chart provides two ways to configure the application:

  1. Built-in Values - Common configuration options available in values.yaml
  2. Custom Environment Variables - For advanced settings not included in the default chart

Understanding values.yaml

The Helm chart uses a hierarchical values.yaml file to configure GeoPulse. When you install or upgrade the chart, you can override these values:

# Option 1: Command-line flags
helm install geopulse ./helm/geopulse --set config.admin.email="admin@example.com"

# Option 2: Custom values file (recommended)
helm install geopulse ./helm/geopulse -f my-values.yaml

Built-in Configuration Options

The following features are natively supported in the Helm chart and can be configured via values.yaml.

Core Configuration

Featurevalues.yaml PathEnvironment VariableDefault
Frontend URLconfig.uiUrlGEOPULSE_UI_URLhttp://localhost:5555
Cookie Domainconfig.cookieDomainGEOPULSE_COOKIE_DOMAIN"" (empty)
Secure Cookiesconfig.authSecureCookiesGEOPULSE_AUTH_SECURE_COOKIESfalse

Admin Configuration

Featurevalues.yaml PathEnvironment VariableDefault
Admin Emailconfig.admin.emailGEOPULSE_ADMIN_EMAIL""

Example:

config:
admin:
email: "admin@example.com"

Authentication & Registration

Featurevalues.yaml PathEnvironment VariableDefault
Registration Enabledconfig.auth.registrationEnabledGEOPULSE_AUTH_REGISTRATION_ENABLEDtrue
Password Registrationconfig.auth.passwordRegistrationEnabledGEOPULSE_AUTH_PASSWORD_REGISTRATION_ENABLEDtrue
OIDC Registrationconfig.auth.oidcRegistrationEnabledGEOPULSE_AUTH_OIDC_REGISTRATION_ENABLEDtrue

Example:

config:
auth:
registrationEnabled: false # Disable all registration
passwordRegistrationEnabled: false # Disable password registration only
oidcRegistrationEnabled: true # Allow OIDC registration

JWT Configuration

Featurevalues.yaml PathEnvironment VariableDefault
Access Token Lifespanconfig.jwt.accessTokenLifespanGEOPULSE_JWT_ACCESS_TOKEN_LIFESPAN1800 (30 min)
Refresh Token Lifespanconfig.jwt.refreshTokenLifespanGEOPULSE_JWT_REFRESH_TOKEN_LIFESPAN604800 (7 days)
JWT Issuerconfig.jwt.issuerGEOPULSE_JWT_ISSUERhttp://localhost:8080
Public Key Locationconfig.jwt.publicKeyLocationGEOPULSE_JWT_PUBLIC_KEY_LOCATIONfile:/app/keys/jwt-public-key.pem
Private Key Locationconfig.jwt.privateKeyLocationGEOPULSE_JWT_PRIVATE_KEY_LOCATIONfile:/app/keys/jwt-private-key.pem

Example:

config:
jwt:
accessTokenLifespan: 3600 # 1 hour
refreshTokenLifespan: 2592000 # 30 days
issuer: "https://geopulse.example.com"

GPS Filtering

Featurevalues.yaml PathEnvironment VariableDefault
Filter Inaccurate Dataconfig.gps.filterInaccurateDataGEOPULSE_GPS_FILTER_INACCURATE_DATA_ENABLEDtrue
Max Allowed Accuracyconfig.gps.maxAllowedAccuracyGEOPULSE_GPS_MAX_ALLOWED_ACCURACY100 meters
Max Allowed Speedconfig.gps.maxAllowedSpeedGEOPULSE_GPS_MAX_ALLOWED_SPEED250 m/s

Example:

config:
gps:
filterInaccurateData: true
maxAllowedAccuracy: 50 # More strict filtering
maxAllowedSpeed: 200

Prometheus Metrics

Featurevalues.yaml PathEnvironment VariableDefault
Enabledconfig.prometheus.enabledGEOPULSE_PROMETHEUS_ENABLEDfalse
Refresh Intervalconfig.prometheus.refreshIntervalGEOPULSE_PROMETHEUS_REFRESH_INTERVAL10m
GPS Points Metricsconfig.prometheus.gpsPoints.enabledGEOPULSE_PROMETHEUS_GPS_POINTS_ENABLEDtrue
User Metricsconfig.prometheus.userMetrics.enabledGEOPULSE_PROMETHEUS_USER_METRICS_ENABLEDtrue
Timeline Metricsconfig.prometheus.timeline.enabledGEOPULSE_PROMETHEUS_TIMELINE_ENABLEDtrue
Favorites Metricsconfig.prometheus.favorites.enabledGEOPULSE_PROMETHEUS_FAVORITES_ENABLEDtrue
Geocoding Metricsconfig.prometheus.geocoding.enabledGEOPULSE_PROMETHEUS_GEOCODING_ENABLEDtrue
Memory Metricsconfig.prometheus.memory.enabledGEOPULSE_PROMETHEUS_MEMORY_ENABLEDtrue

Example:

config:
prometheus:
enabled: true
refreshInterval: "5m"
# Optionally disable specific metric classes
memory:
enabled: false

Geocoding Configuration

Featurevalues.yaml PathEnvironment VariableDefault
Primary Providerconfig.geocoding.primaryProviderGEOPULSE_GEOCODING_PRIMARY_PROVIDERnominatim
Fallback Providerconfig.geocoding.fallbackProviderGEOPULSE_GEOCODING_FALLBACK_PROVIDER""
Delay (ms)config.geocoding.delayMsGEOPULSE_GEOCODING_DELAY_MS1000
Nominatim Enabledconfig.geocoding.nominatim.enabledGEOPULSE_GEOCODING_NOMINATIM_ENABLEDtrue
Nominatim URLconfig.geocoding.nominatim.urlGEOPULSE_GEOCODING_NOMINATIM_URLhttps://nominatim.openstreetmap.org
Photon Enabledconfig.geocoding.photon.enabledGEOPULSE_GEOCODING_PHOTON_ENABLEDfalse
Photon URLconfig.geocoding.photon.urlGEOPULSE_GEOCODING_PHOTON_URLhttps://photon.komoot.io
Google Maps Enabledconfig.geocoding.googleMaps.enabledGEOPULSE_GEOCODING_GOOGLE_MAPS_ENABLEDfalse
Google Maps API Keyconfig.geocoding.googleMaps.apiKeyGEOPULSE_GEOCODING_GOOGLE_MAPS_API_KEY"" (secret)
Mapbox Enabledconfig.geocoding.mapbox.enabledGEOPULSE_GEOCODING_MAPBOX_ENABLEDfalse
Mapbox Access Tokenconfig.geocoding.mapbox.accessTokenGEOPULSE_GEOCODING_MAPBOX_ACCESS_TOKEN"" (secret)

Example:

config:
geocoding:
primaryProvider: "googlemaps"
fallbackProvider: "nominatim"
delayMs: 500
googleMaps:
enabled: true
apiKey: "your-api-key-here" # Stored in Kubernetes Secret
nominatim:
enabled: true

Location Sharing

Featurevalues.yaml PathEnvironment VariableDefault
Base URL Overrideconfig.share.baseUrlGEOPULSE_SHARE_BASE_URL"" (uses window.location.origin)

Example:

config:
share:
baseUrl: "https://share.geopulse.example.com"

User Invitation

Featurevalues.yaml PathEnvironment VariableDefault
Base URL Overrideconfig.invitation.baseUrlGEOPULSE_INVITATION_BASE_URL"" (uses window.location.origin)

Example:

config:
share:
baseUrl: "https://invite.geopulse.example.com"

OwnTracks

Featurevalues.yaml PathEnvironment VariableDefault
Ping Timestamp Overrideconfig.owntracks.pingTimestampOverrideGEOPULSE_OWNTRACKS_PING_TIMESTAMP_OVERRIDEfalse

Example:

config:
owntracks:
pingTimestampOverride: true

OIDC / SSO Configuration

Featurevalues.yaml PathEnvironment VariableDefault
OIDC Enabledconfig.oidc.enabledGEOPULSE_OIDC_ENABLEDfalse
Auto-Link Accountsconfig.oidc.autoLinkAccountsGEOPULSE_OIDC_AUTO_LINK_ACCOUNTSfalse
Cleanup Enabledconfig.oidc.cleanupEnabledGEOPULSE_OIDC_CLEANUP_ENABLEDtrue

Google OIDC

config:
oidc:
enabled: true
google:
enabled: true
clientId: "your-google-client-id.apps.googleusercontent.com"
clientSecret: "your-google-client-secret" # Stored in Kubernetes Secret

Microsoft OIDC

config:
oidc:
enabled: true
microsoft:
enabled: true
clientId: "your-microsoft-client-id"
clientSecret: "your-microsoft-client-secret" # Stored in Kubernetes Secret

Generic OIDC (Keycloak, Authentik, Okta, etc.)

config:
oidc:
enabled: true
generic:
enabled: true
name: "Keycloak" # Display name in UI
clientId: "geopulse"
clientSecret: "your-keycloak-client-secret" # Stored in Kubernetes Secret
discoveryUrl: "https://keycloak.example.com/realms/master/.well-known/openid-configuration"

Advanced Configuration: Custom Environment Variables

Some GeoPulse features are not exposed in the default Helm chart values.yaml. For these advanced settings, you can add custom environment variables to the backend deployment.

Method 1: Using extraEnv in values.yaml

This is the recommended approach for most custom configuration needs.

Step 1: Create a custom values file (custom-values.yaml):

backend:
extraEnv:
- name: GEOPULSE_TIMELINE_PROCESSING_THREADS
value: "4"
- name: GEOPULSE_TIMELINE_VIEW_ITEM_LIMIT
value: "200"
- name: GEOPULSE_IMPORT_BULK_INSERT_BATCH_SIZE
value: "1000"

Step 2: Apply the configuration:

helm upgrade geopulse ./helm/geopulse -f custom-values.yaml

Method 2: Using ConfigMap for Multiple Variables

For many custom variables, create a dedicated ConfigMap:

Step 1: Create custom-config.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
name: geopulse-custom-config
namespace: default
data:
GEOPULSE_TIMELINE_PROCESSING_THREADS: "4"
GEOPULSE_TIMELINE_VIEW_ITEM_LIMIT: "200"
GEOPULSE_IMPORT_BULK_INSERT_BATCH_SIZE: "1000"
GEOPULSE_TIMELINE_STAYPOINT_RADIUS_METERS: "75"

Step 2: Apply the ConfigMap:

kubectl apply -f custom-config.yaml

Step 3: Reference it in your values file:

backend:
extraEnvFrom:
- configMapRef:
name: geopulse-custom-config

Method 3: Using Secrets for Sensitive Data

For sensitive configuration like API keys:

Step 1: Create a Kubernetes Secret:

kubectl create secret generic geopulse-extra-secrets \
--from-literal=GEOPULSE_AI_SOME_API_KEY='your-secret-key'

Step 2: Reference it in values:

backend:
extraEnv:
- name: GEOPULSE_AI_SOME_API_KEY
valueFrom:
secretKeyRef:
name: geopulse-extra-secrets
key: GEOPULSE_AI_SOME_API_KEY

Managing Secrets in Kubernetes

Best Practices

  1. Never commit secrets to Git - Use .gitignore for values files with secrets
  2. Use Kubernetes Secrets - Store sensitive data in Secret objects, not ConfigMaps
  3. Consider External Secret Managers - For production, use AWS Secrets Manager, HashiCorp Vault, or similar
  4. Rotate secrets regularly - Update secrets periodically and restart pods

Using Sealed Secrets

For GitOps workflows, consider using Sealed Secrets:

# Install Sealed Secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# Create a sealed secret
echo -n 'your-secret-value' | kubectl create secret generic mysecret --dry-run=client --from-file=api-key=/dev/stdin -o yaml | \
kubeseal -o yaml > sealed-secret.yaml

# Commit sealed-secret.yaml to Git safely

Common Configuration Scenarios

Production Setup with HTTPS

# production-values.yaml
config:
uiUrl: "https://geopulse.example.com"
authSecureCookies: true
admin:
email: "admin@example.com"
oidc:
enabled: true
google:
enabled: true
clientId: "..."
clientSecret: "..."

ingress:
enabled: true
className: "nginx"
hostname: geopulse.example.com
tls:
enabled: true
secretName: geopulse-tls
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"

Self-Hosted Geocoding

config:
geocoding:
primaryProvider: "nominatim"
nominatim:
enabled: true
url: "https://nominatim.mycompany.internal"
# Self-hosted Photon as fallback
fallbackProvider: "photon"
photon:
enabled: true
url: "https://photon.mycompany.internal"

High-Performance Import Configuration

backend:
resources:
limits:
memory: 4Gi
cpu: 2000m
extraEnv:
- name: GEOPULSE_IMPORT_BULK_INSERT_BATCH_SIZE
value: "2000"
- name: GEOPULSE_IMPORT_MERGE_BATCH_SIZE
value: "1000"
- name: GEOPULSE_IMPORT_LARGE_FILE_THRESHOLD_MB
value: "200"
- name: GEOPULSE_TIMELINE_PROCESSING_THREADS
value: "4"

Monitoring with Prometheus

config:
prometheus:
enabled: true
refreshInterval: "5m"
# All metrics enabled by default

# Optional: If using Prometheus Operator
serviceMonitor:
enabled: true
interval: 30s
path: /api/prometheus/metrics

Feature Configuration Reference

For detailed configuration of specific features, see:

Troubleshooting

Configuration Not Applied

If your configuration changes aren't taking effect:

  1. Verify the values are set:

    helm get values geopulse
  2. Check the ConfigMap:

    kubectl get configmap geopulse-config -o yaml
  3. Restart the backend pod:

    kubectl rollout restart deployment geopulse-backend

Finding Environment Variables

To see all environment variables in the running backend:

kubectl exec -it deployment/geopulse-backend -- env | grep GEOPULSE | sort

Validating Secrets

Check if secrets are properly set:

# List secret keys (values are base64 encoded)
kubectl get secret geopulse-secret -o jsonpath='{.data}' | jq 'keys'

# Decode a specific secret (be careful with sensitive data)
kubectl get secret geopulse-secret -o jsonpath='{.data.GEOPULSE_ADMIN_EMAIL}' | base64 -d

Upgrading the Chart

When upgrading to a new version:

# See what will change
helm diff upgrade geopulse ./helm/geopulse -f my-values.yaml

# Upgrade the release
helm upgrade geopulse ./helm/geopulse -f my-values.yaml

# Rollback if needed
helm rollback geopulse

Additional Resources