HitKeep mit Helm auf Kubernetes bereitstellen
Stelle HitKeep mit dem offiziellen Helm-Chart in deinem Kubernetes-Cluster bereit, wenn dein Cluster bereits Helm nutzt. Der Chart erstellt ein StatefulSet, einen ClusterIP-Service, einen Headless-Service für das Clustering, optionalen Ingress und persistenten Speicher für HitKeeps DuckDB-Dateien und lokale Assets.
Verwende das einfache Manifest weiter unten, wenn du Helm nicht nutzt oder alle Kubernetes-Objekte sichtbar in einer Datei haben möchtest.
Schnellstart
Abschnitt betitelt „Schnellstart“Mit Helm installieren
Abschnitt betitelt „Mit Helm installieren“Der Chart wird als OCI-Artefakt in der GitHub Container Registry veröffentlicht:
helm show values oci://ghcr.io/pascalebeier/charts/hitkeep --version 2.13.18Erstelle vor der Installation einen Namespace und speichere das JWT-Signaturgeheimnis:
kubectl create namespace analyticskubectl -n analytics create secret generic hitkeep-secrets \ --from-literal=jwt-secret="$(openssl rand -hex 32)"Speichere Folgendes als hitkeep-values.yaml:
domain: analytics.example.com
ingress: enabled: true className: ""
persistence: enabled: true size: 10Gi accessMode: ReadWriteOnce
env: HITKEEP_PUBLIC_URL: "https://analytics.example.com"
extraEnv: - name: HITKEEP_JWT_SECRET valueFrom: secretKeyRef: name: hitkeep-secrets key: jwt-secretInstalliere den Chart:
helm install hitkeep oci://ghcr.io/pascalebeier/charts/hitkeep --namespace analytics --version 2.13.18 -f hitkeep-values.yaml
kubectl -n analytics rollout status statefulset/hitkeepWenn dein Cluster keinen Ingress-Controller besitzt, lasse ingress.enabled auf false und veröffentliche den Service nach dem üblichen Muster deines Clusters.
Installation prüfen
Abschnitt betitelt „Installation prüfen“Prüfe, ob das StatefulSet vollständig ausgerollt und der PersistentVolumeClaim gebunden ist:
kubectl -n analytics rollout status statefulset/hitkeepkubectl -n analytics get pods,pvckubectl -n analytics port-forward service/hitkeep 8080:80Prüfe bei laufendem Port-Forward beide Endpunkte in einem weiteren Terminal:
curl --fail http://localhost:8080/healthzcurl --fail http://localhost:8080/readyz/healthz bestätigt, dass der Prozess läuft. /readyz bestätigt, dass die gemeinsame Datenbank und jede geöffnete Mandantendatenbank bereit sind.
Zu prüfende Chart-Werte
Abschnitt betitelt „Zu prüfende Chart-Werte“| Wert | Standard | Verwendung |
|---|---|---|
image.repository | ghcr.io/pascalebeier/hitkeep | Repository des Container-Images. |
image.tag | App-Version des Charts ohne führendes v | Nur überschreiben, wenn du bewusst ein anderes App-Image als die Chart-Version ausführst. |
env.HITKEEP_PUBLIC_URL | http://localhost:8080 | Im Browser sichtbare URL für HitKeep. Für den Produktivbetrieb festlegen. |
extraEnv | [] | Aus Secrets bezogene Werte wie HITKEEP_JWT_SECRET, SMTP- oder S3-Zugangsdaten und KI-Provider-Token. |
persistence.enabled | true | Erstellt eine VolumeClaimTemplate des StatefulSets für HitKeeps Datenverzeichnis. |
persistence.mountPath | /var/lib/hitkeep/data | Persistenter Mount für die folgenden Chart-Standardwerte. |
ingress.enabled | false | Erstellt einen Ingress für den Ingress-Controller deines Clusters. |
customTrackingDomains.enabled | false | Konfiguriert HitKeeps Laufzeiteinstellungen für eigene Tracking-Domains. |
customTrackingDomains.ingress.enabled | false | Erstellt einen separaten reinen Tracking-Ingress für statische Tracker-Hostnamen. |
service.type | ClusterIP | Nutze LoadBalancer oder NodePort nur, wenn das zu deinem Cluster passt. |
replicaCount | 1 | Setze den Wert nur dann auf 2 oder höher, wenn du HitKeep-Clustering benötigst. |
Der Chart setzt diese Pfade, sofern du sie nicht unter env überschreibst:
| Umgebungsvariable | Chart-Standardwert |
|---|---|
HITKEEP_DB_PATH | /var/lib/hitkeep/data/hitkeep.db |
HITKEEP_DATA_PATH | /var/lib/hitkeep/data |
HITKEEP_ARCHIVE_PATH | /var/lib/hitkeep/data/archive |
HITKEEP_SPAM_FILTER_PATH | /var/lib/hitkeep/data/spam-filter.json |
Mit diesen Standardwerten speichert derselbe PVC die gemeinsame DuckDB-Datenbank, die DuckDB-Datenbanken der Mandanten, QR-Code-Grafiken unter assets/qr-codes, Archivdateien und den optionalen lokalen Spamfilter-Cache.
Eigene Tracking-Domains
Abschnitt betitelt „Eigene Tracking-Domains“Der Helm-Chart unterstützt eigene Tracking-Domains, ohne einen Ingress-Controller mitzuliefern. Nutze denselben Dashboard-Ablauf wie bei anderen selbst gehosteten Installationen: Füge die Domain in den Team-Einstellungen hinzu, veröffentliche den TXT-Eigentumsnachweis, richte DNS auf das Ingress-Ziel und verifiziere die Domain, sobald TLS bereit ist.
Nutze für übliche Kubernetes-Ingress-Controller den externen TLS-Modus:
customTrackingDomains: enabled: true tlsMode: external # Empty defaults to the host from env.HITKEEP_PUBLIC_URL. # Set this when tracker domains point at a separate ingress hostname or IP. dnsTarget: "" ingress: enabled: true className: nginx annotations: cert-manager.io/cluster-issuer: letsencrypt-prod hosts: - host: tracker.customer-one.example - host: tracker.customer-two.example tls: - hosts: - tracker.customer-one.example - tracker.customer-two.example secretName: hitkeep-tracking-tlsDer Chart erzeugt einen separaten Tracking-Ingress, der nach dem Helm-Release benannt ist, beispielsweise hitkeep-tracking. Er leitet ausschließlich /hk.js, /hk-vitals.js, /ingest, /ingest/event und /ingest/web-vitals an HitKeep weiter. Dashboard-, API-, Auth-, Share-, MCP-, QR- und SPA-Fallback-Routen gehören nicht zu diesem Ingress. HitKeep setzt die Beschränkung auf Tracking-Hosts zusätzlich intern durch.
Stelle Caddy für On-Demand-TLS separat bereit und speichere das Ask-Token in einem Kubernetes-Secret:
kubectl -n analytics create secret generic hitkeep-caddy-ask \ --from-literal=token="$(openssl rand -hex 32)"customTrackingDomains: enabled: true tlsMode: caddy-on-demand caddyAskToken: existingSecret: hitkeep-caddy-ask existingSecretKey: token ingress: enabled: falseKonfiguriere den externen Caddy-Listener mit ask http://hitkeep.analytics.svc.cluster.local/internal/caddy/on-demand-tls/<token>. Caddy sendet ?domain= an diese URL, bevor es ein Zertifikat ausstellt. HitKeep erlaubt nur aktivierte, per DNS verifizierte eigene Tracking-Domains.
Upgrade
Abschnitt betitelt „Upgrade“Bewahre deine hitkeep-values.yaml in der Versionsverwaltung oder deinem Bereitstellungssystem auf. Aktualisiere Chart und App-Image gemeinsam, indem du ausschließlich die Chart-Version änderst:
helm upgrade hitkeep oci://ghcr.io/pascalebeier/charts/hitkeep --namespace analytics --version 2.13.18 -f hitkeep-values.yaml
kubectl -n analytics rollout status statefulset/hitkeepLies vor Upgrades über Feature-Releases hinweg die Release Notes, insbesondere wenn du optionale Integrationen wie MCP, KI-Modellkonfiguration, Google Search Console, SMTP oder S3-Backups nutzt.
Optionale MCP- und KI-Konfiguration
Abschnitt betitelt „Optionale MCP- und KI-Konfiguration“MCP und KI-gestützte Produktfunktionen bleiben deaktiviert, bis du sie aktivierst und konfigurierst. Nutze env für nicht geheime Einstellungen und extraEnv für Token.
env: HITKEEP_MCP_ENABLED: "true" HITKEEP_MCP_PATH: "/mcp" HITKEEP_MCP_MAX_RANGE_DAYS: "366" HITKEEP_AI_ENABLED: "true" HITKEEP_AI_PROVIDER: "openai-compatible" HITKEEP_AI_MODEL: "opportunities-json"
extraEnv: - name: HITKEEP_AI_API_KEY valueFrom: secretKeyRef: name: hitkeep-ai key: api-keyLies vor der Aktivierung im Produktivbetrieb Offizieller MCP-Server und KI-Modellkonfiguration.
Einfaches Kubernetes-Manifest
Abschnitt betitelt „Einfaches Kubernetes-Manifest“Nutze dieses Manifest, wenn du Helm nicht verwendest. Die HitKeep-Laufzeitpfade entsprechen denen des offiziellen Charts.
Speichere es als hitkeep.yaml:
apiVersion: v1kind: Namespacemetadata:name: analytics---apiVersion: v1kind: Secretmetadata:name: hitkeep-secretsnamespace: analyticstype: OpaquestringData:jwt-secret: "change-me-to-a-long-random-string"---apiVersion: v1kind: PersistentVolumeClaimmetadata:name: hitkeep-datanamespace: analyticsspec:accessModes: ["ReadWriteOnce"]resources: requests: storage: 10Gi---apiVersion: v1kind: Servicemetadata:name: hitkeep-headlessnamespace: analyticsspec:clusterIP: NonepublishNotReadyAddresses: trueselector: app: hitkeepports: - name: gossip-tcp port: 7946 protocol: TCP targetPort: gossip-tcp - name: gossip-udp port: 7946 protocol: UDP targetPort: gossip-udp---apiVersion: v1kind: Servicemetadata:name: hitkeepnamespace: analyticsspec:type: ClusterIPselector: app: hitkeepports: - name: http protocol: TCP port: 80 targetPort: http---apiVersion: apps/v1kind: StatefulSetmetadata:name: hitkeepnamespace: analyticsspec:serviceName: hitkeep-headlessreplicas: 1selector: matchLabels: app: hitkeeptemplate: metadata: labels: app: hitkeep spec: securityContext: runAsNonRoot: true runAsUser: 65532 runAsGroup: 65532 fsGroup: 65532 containers: - name: hitkeep image: ghcr.io/pascalebeier/hitkeep:2.13.18 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 name: http - containerPort: 7946 name: gossip-tcp protocol: TCP - containerPort: 7946 name: gossip-udp protocol: UDP env: - name: HITKEEP_HTTP_ADDR value: ":8080" - name: HITKEEP_PUBLIC_URL value: "https://analytics.example.com" - name: HITKEEP_DB_PATH value: "/var/lib/hitkeep/data/hitkeep.db" - name: HITKEEP_DATA_PATH value: "/var/lib/hitkeep/data" - name: HITKEEP_ARCHIVE_PATH value: "/var/lib/hitkeep/data/archive" - name: HITKEEP_SPAM_FILTER_PATH value: "/var/lib/hitkeep/data/spam-filter.json" - name: HITKEEP_JWT_SECRET valueFrom: secretKeyRef: name: hitkeep-secrets key: jwt-secret volumeMounts: - mountPath: /var/lib/hitkeep/data name: data livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: path: /readyz port: http initialDelaySeconds: 5 periodSeconds: 10 volumes: - name: data persistentVolumeClaim: claimName: hitkeep-dataWende es an:
kubectl apply -f hitkeep.yamlkubectl -n analytics rollout status statefulset/hitkeepErgänze deine Ingress-Ressource oder einen externen Service passend zum üblichen Ingress-Controller- oder Load-Balancer-Aufbau deines Clusters.
Zustands- und Bereitschaftsprüfungen
Abschnitt betitelt „Zustands- und Bereitschaftsprüfungen“HitKeep stellt zwei Prüfendpunkte für Kubernetes bereit:
| Endpunkt | Zweck |
|---|---|
GET /healthz | Liveness: Der Prozess läuft. |
GET /readyz | Readiness: Die gemeinsame Datenbank und jede aktuell geöffnete Mandantendatenbank sind fehlerfrei. |
Diese Endpunkte bleiben am lokalen Root verfügbar, auch wenn HITKEEP_PUBLIC_URL ein Pfadpräfix enthält.
Während einer Datenbankwiederherstellung bleibt /healthz erfolgreich, damit der Kubelet keinen Prozess beendet, der gerade sichere Wiederherstellungsarbeiten ausführt. /readyz antwortet mit 503, Retry-After: 5 und einem JSON-Grund wie database_recovering oder database_needs_attention. Dadurch wird der Pod aus dem Service genommen, bis die Datenbank wieder fehlerfrei ist.
Vertrauenswürdige Proxys
Abschnitt betitelt „Vertrauenswürdige Proxys“Wenn dein Cluster einen Ingress-Controller wie nginx-ingress, Traefik oder AWS ALB nutzt, konfiguriere vertrauenswürdige Proxy-CIDRs, damit echte Client-IPs für Webanalyse und Ratenbegrenzung verwendet werden:
env: HITKEEP_TRUSTED_PROXIES: "10.0.0.0/8"Weitere Einzelheiten findest du unter Vertrauenswürdige Proxys.
Sichere den vollständigen persistenten Datenpfad. Bei den Standardwerten des Helm-Charts und des einfachen Manifests oben sind diese Laufzeitpfade wichtig:
/var/lib/hitkeep/data/hitkeep.dbfür gemeinsame Control-Plane-Daten/var/lib/hitkeep/data/tenants/*/hitkeep.dbfür Analysedaten von Teams außerhalb des Standardmandanten/var/lib/hitkeep/data/assets/qr-codes/*für QR-Code-Grafiken/var/lib/hitkeep/data/archivefür lokale Archivartefakte/var/lib/hitkeep/data/backups, wenn duHITKEEP_BACKUP_PATHauf diesen lokalen Pfad setzt/var/lib/hitkeep/data/recoveryfür zugriffsgeschützte automatische Wiederherstellungspakete und fortsetzbare Marker, sofern duHITKEEP_DB_RECOVERY_PATHnicht überschreibst
Aktiviere lokale automatische Backup-Snapshots auf demselben PVC so:
env: HITKEEP_BACKUP_PATH: "/var/lib/hitkeep/data/backups" HITKEEP_BACKUP_INTERVAL: "60" HITKEEP_BACKUP_RETENTION: "24"Nutze für Backup-Speicher außerhalb des Clusters einen s3://-Wert für HITKEEP_BACKUP_PATH und konfiguriere die S3-Umgebungsvariablen in einem Kubernetes-Secret. Beispiele findest du unter S3-Backups.
Verwandte Themen
Abschnitt betitelt „Verwandte Themen“- Docker-Compose-Installation
- Vertrauenswürdige Proxys
- Backups und Wiederherstellung
- S3-Backups
- Konfigurationsreferenz
- Architektur
Du betreibst HitKeep auf Kubernetes, möchtest aber StatefulSets, PVCs und Cluster-Upgrades nicht selbst verwalten? HitKeep Cloud übernimmt die Infrastruktur in der von dir gewählten verwalteten Region.