Desplegar HitKeep en Kubernetes con Helm
Despliega HitKeep en tu clúster de Kubernetes con el chart oficial de Helm si el clúster ya usa Helm. El chart crea un StatefulSet, un Service ClusterIP, un Service headless para el clúster, un Ingress opcional y almacenamiento persistente para los archivos de DuckDB y los recursos locales de HitKeep.
Usa el manifiesto sencillo que aparece más adelante si no utilizas Helm o quieres ver todos los objetos de Kubernetes en un único archivo.
Inicio rápido
Section titled “Inicio rápido”Instalar con Helm
Section titled “Instalar con Helm”El chart se publica como artefacto OCI en GitHub Container Registry:
helm show values oci://ghcr.io/pascalebeier/charts/hitkeep --version 2.14.1Crea un namespace y guarda el secreto para firmar JWT antes de instalar:
kubectl create namespace analyticskubectl -n analytics create secret generic hitkeep-secrets \ --from-literal=jwt-secret="$(openssl rand -hex 32)"Guarda lo siguiente como 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-secretInstala el chart:
helm install hitkeep oci://ghcr.io/pascalebeier/charts/hitkeep --namespace analytics --version 2.14.1 -f hitkeep-values.yaml
kubectl -n analytics rollout status statefulset/hitkeepSi tu clúster no tiene un controlador de Ingress, conserva ingress.enabled como false y publica el Service siguiendo el patrón habitual de tu clúster.
Verificación
Section titled “Verificación”Confirma que el StatefulSet ha completado el despliegue y que la reclamación de volumen persistente está enlazada:
kubectl -n analytics rollout status statefulset/hitkeepkubectl -n analytics get pods,pvckubectl -n analytics port-forward service/hitkeep 8080:80Mientras el reenvío de puerto esté activo, comprueba ambos endpoints desde otra terminal:
curl --fail http://localhost:8080/healthzcurl --fail http://localhost:8080/readyz/healthz confirma que el proceso está activo. /readyz confirma que la base de datos compartida y todas las bases de datos de tenants abiertas están listas.
Valores del chart que debes revisar
Section titled “Valores del chart que debes revisar”| Valor | Predeterminado | Uso |
|---|---|---|
image.repository | ghcr.io/pascalebeier/hitkeep | Repositorio de la imagen de contenedor. |
image.tag | versión de la aplicación del chart, sin la v inicial | Cámbialo únicamente si quieres ejecutar deliberadamente una imagen de la aplicación distinta de la versión del chart. |
env.HITKEEP_PUBLIC_URL | http://localhost:8080 | URL visible en el navegador para acceder a HitKeep. Defínela en producción. |
extraEnv | [] | Valores respaldados por secretos, como HITKEEP_JWT_SECRET, credenciales SMTP o S3 y tokens de proveedores de IA. |
persistence.enabled | true | Crea una plantilla de reclamación de volumen del StatefulSet para el directorio de datos de HitKeep. |
persistence.mountPath | /var/lib/hitkeep/data | Punto de montaje persistente usado por los valores predeterminados del chart que aparecen a continuación. |
ingress.enabled | false | Crea un Ingress para el controlador de Ingress del clúster. |
customTrackingDomains.enabled | false | Configura los ajustes de ejecución de HitKeep para dominios de seguimiento personalizados. |
customTrackingDomains.ingress.enabled | false | Crea un Ingress independiente, limitado al seguimiento, para hostnames estáticos del tracker. |
service.type | ClusterIP | Usa LoadBalancer o NodePort solo si encaja con tu clúster. |
replicaCount | 1 | Usa 2 o más únicamente si quieres un clúster de HitKeep. |
El chart define estas rutas salvo que las sobrescribas en env:
| Variable de entorno | Valor predeterminado del chart |
|---|---|
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 |
Con estos valores, el mismo PVC almacena la base de datos DuckDB compartida, las bases de datos DuckDB de los tenants, los recursos gráficos de códigos QR en assets/qr-codes, los archivos y la caché local opcional del filtro de spam.
Dominios de seguimiento personalizados
Section titled “Dominios de seguimiento personalizados”El chart de Helm admite dominios de seguimiento personalizados sin incluir un controlador de Ingress. Usa el mismo flujo del panel que en otras instalaciones autogestionadas: añade el dominio en los ajustes del equipo, publica el registro TXT de propiedad, dirige el DNS al destino del Ingress y verifica cuando TLS esté listo.
Con controladores de Ingress habituales de Kubernetes, usa el modo TLS externo:
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-tlsEl chart emite un Ingress de seguimiento independiente cuyo nombre deriva de la instalación de Helm, por ejemplo hitkeep-tracking. Solo enruta /hk.js, /hk-vitals.js, /ingest, /ingest/event y /ingest/web-vitals hacia HitKeep. El panel, la API, la autenticación, los enlaces compartidos, MCP, QR y las rutas alternativas de la SPA no forman parte de ese Ingress. HitKeep también aplica internamente este límite para los hosts de seguimiento.
Para TLS bajo demanda de Caddy, despliega Caddy por separado y conserva el token de consulta en un Secret de Kubernetes:
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: falseConfigura el listener externo de Caddy con ask http://hitkeep.analytics.svc.cluster.local/internal/caddy/on-demand-tls/<token>. Caddy envía ?domain= a esa URL antes de emitir un certificado y HitKeep solo permite dominios de seguimiento personalizados activados y verificados mediante DNS.
Actualización
Section titled “Actualización”Conserva hitkeep-values.yaml bajo control de versiones o en tu sistema de despliegue. Actualiza juntos el chart y la imagen de la aplicación cambiando únicamente la versión del chart:
helm upgrade hitkeep oci://ghcr.io/pascalebeier/charts/hitkeep --namespace analytics --version 2.14.1 -f hitkeep-values.yaml
kubectl -n analytics rollout status statefulset/hitkeepRevisa las notas de la versión antes de actualizar entre versiones con funcionalidades distintas, sobre todo si usas integraciones opcionales como MCP, configuración de modelos de IA, Google Search Console, SMTP o copias de seguridad en S3.
Configuración opcional de MCP e IA
Section titled “Configuración opcional de MCP e IA”MCP y las funcionalidades del producto basadas en IA permanecen desactivadas hasta que las habilites y configures. Usa env para ajustes no sensibles y extraEnv para tokens.
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-keyConsulta Servidor MCP oficial y Configuración de modelos de IA antes de activarlos en producción.
Manifiesto sencillo de Kubernetes
Section titled “Manifiesto sencillo de Kubernetes”Usa este manifiesto si no utilizas Helm. Mantiene las rutas de ejecución de HitKeep alineadas con el chart oficial.
Guárdalo como 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.14.1 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-dataAplícalo:
kubectl apply -f hitkeep.yamlkubectl -n analytics rollout status statefulset/hitkeepAñade tu recurso Ingress o un Service externo de acuerdo con el controlador de Ingress o el balanceador de carga habitual del clúster.
Comprobaciones de actividad y disponibilidad
Section titled “Comprobaciones de actividad y disponibilidad”HitKeep expone dos endpoints de comprobación para Kubernetes:
| Endpoint | Finalidad |
|---|---|
GET /healthz | Actividad. El proceso está en ejecución. |
GET /readyz | Disponibilidad. La base de datos compartida y todas las bases de datos de tenants abiertas están en buen estado. |
Estos endpoints siguen disponibles en la raíz local aunque HITKEEP_PUBLIC_URL incluya un prefijo de ruta.
Durante la recuperación de la base de datos, /healthz sigue respondiendo correctamente para que kubelet no termine un proceso que está realizando una recuperación segura. /readyz responde con 503, Retry-After: 5 y un motivo JSON como database_recovering o database_needs_attention, por lo que el pod queda fuera de servicio hasta que la base de datos vuelva a estar en buen estado.
Proxies de confianza
Section titled “Proxies de confianza”Si tu clúster usa un controlador de Ingress como nginx-ingress, Traefik o AWS ALB, configura los CIDR de proxies de confianza para usar las IP reales de clientes en la analítica y los límites de solicitudes:
env: HITKEEP_TRUSTED_PROXIES: "10.0.0.0/8"Consulta Proxies de confianza para obtener más información.
Copias de seguridad
Section titled “Copias de seguridad”Crea copias de toda la ruta de datos persistente. Con los valores predeterminados del chart de Helm y el manifiesto sencillo anterior, las rutas de ejecución importantes son:
/var/lib/hitkeep/data/hitkeep.dbpara los datos compartidos del plano de control/var/lib/hitkeep/data/tenants/*/hitkeep.dbpara los datos de analítica de los equipos no predeterminados/var/lib/hitkeep/data/assets/qr-codes/*para los recursos gráficos de códigos QR/var/lib/hitkeep/data/archivepara los archivos locales/var/lib/hitkeep/data/backupssi definesHITKEEP_BACKUP_PATHcon esa ruta local/var/lib/hitkeep/data/recoverypara paquetes de recuperación automática y marcadores reanudables con permisos restringidos, salvo que sobrescribasHITKEEP_DB_RECOVERY_PATH
Para activar instantáneas automáticas locales en el mismo PVC:
env: HITKEEP_BACKUP_PATH: "/var/lib/hitkeep/data/backups" HITKEEP_BACKUP_INTERVAL: "60" HITKEEP_BACKUP_RETENTION: "24"Para almacenar copias fuera del clúster, usa una URL s3:// en HITKEEP_BACKUP_PATH y configura las variables de entorno S3 en un Secret de Kubernetes. Consulta Copias de seguridad en S3 para ver ejemplos.
Contenido relacionado
Section titled “Contenido relacionado”- Instalación con Docker Compose
- Proxies de confianza
- Copias de seguridad y restauración
- Copias de seguridad en S3
- Referencia de configuración
- Arquitectura
¿Ejecutas HitKeep en Kubernetes pero no quieres administrar StatefulSets, PVC ni actualizaciones del clúster? Compara HitKeep Cloud.