Skip to content
☁️ HitKeep Cloud is coming! Join the Early Access waitlist →

Kubernetes

Deploy HitKeep in your Kubernetes cluster using a StatefulSet with a PersistentVolumeClaim. The PVC keeps hitkeep.db attached to the pod across restarts — your analytics data stays in your cluster, under your storage policy, in your namespace.

This manifest uses a Kubernetes Secret for the JWT key. Save it as hitkeep.yaml:

apiVersion: v1
kind: Namespace
metadata:
name: analytics
---
apiVersion: v1
kind: Secret
metadata:
name: hitkeep-secrets
namespace: analytics
type: Opaque
stringData:
jwt-secret: "change-me-to-a-long-random-string"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hitkeep-pvc
namespace: analytics
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: hitkeep
namespace: analytics
spec:
serviceName: hitkeep
replicas: 1
selector:
matchLabels:
app: hitkeep
template:
metadata:
labels:
app: hitkeep
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: hitkeep
image: ghcr.io/pascalebeier/hitkeep:latest
ports:
- containerPort: 8080
name: http
env:
- name: HITKEEP_JWT_SECRET
valueFrom:
secretKeyRef:
name: hitkeep-secrets
key: jwt-secret
args:
- "-public-url=https://analytics.example.com"
- "-db=/var/lib/hitkeep/data/hitkeep.db"
- "-archive-path=/var/lib/hitkeep/archive"
volumeMounts:
- mountPath: /var/lib/hitkeep/data
name: data
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: data
persistentVolumeClaim:
claimName: hitkeep-pvc
---
apiVersion: v1
kind: Service
metadata:
name: hitkeep
namespace: analytics
spec:
selector:
app: hitkeep
ports:
- protocol: TCP
port: 80
targetPort: 8080

Apply it:

Terminal window
kubectl apply -f hitkeep.yaml
kubectl -n analytics rollout status statefulset/hitkeep

HitKeep exposes two probe endpoints for Kubernetes:

EndpointPurpose
GET /healthzLiveness — is the process running?
GET /readyzReadiness — is the database connection healthy?

These are included in the manifest above and integrate with your cluster’s existing health check infrastructure.

If your cluster uses an ingress controller (nginx-ingress, Traefik, AWS ALB), configure trusted proxy CIDRs so real client IPs are used for analytics and rate limiting:

args:
- "-trusted-proxies=10.0.0.0/8"

See Trusted Proxies for details.

Back up hitkeep.db from the PVC using a CronJob or a manual copy:

Terminal window
# One-time snapshot
kubectl -n analytics exec statefulset/hitkeep -- \
cp /var/lib/hitkeep/data/hitkeep.db /var/lib/hitkeep/data/hitkeep.db.bak
# Copy out of the pod
kubectl -n analytics cp hitkeep-0:/var/lib/hitkeep/data/hitkeep.db ./hitkeep-backup.db

Running HitKeep in Kubernetes but don’t want to manage StatefulSets, PVCs, and cluster upgrades? HitKeep Cloud → handles the infrastructure while keeping your data in your chosen sovereign region.