Pular para o conteúdo
Começar grátis na Cloud

Implantar o HitKeep no Kubernetes com Helm

Implante o HitKeep no seu cluster Kubernetes com o chart oficial do Helm quando o cluster já usa Helm. O chart cria um StatefulSet, um Service ClusterIP, um Service headless para clustering, um Ingress opcional e armazenamento persistente para os arquivos DuckDB e assets locais do HitKeep.

Use o manifesto simples mais adiante nesta página se não usar Helm ou preferir visualizar todos os objetos Kubernetes em um único arquivo.

O chart é publicado como artefato OCI no GitHub Container Registry:

Janela do terminal
helm show values oci://ghcr.io/pascalebeier/charts/hitkeep --version 2.13.18

Crie um namespace e armazene o segredo de assinatura JWT antes da instalação:

Janela do terminal
kubectl create namespace analytics
kubectl -n analytics create secret generic hitkeep-secrets \
--from-literal=jwt-secret="$(openssl rand -hex 32)"

Salve o seguinte 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-secret

Instale o chart:

Janela do terminal
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/hitkeep

Se o cluster não tiver um controlador de ingress, mantenha ingress.enabled como false e exponha o Service pelo padrão habitual do cluster.

Confirme que o rollout do StatefulSet terminou e que o volume persistente está vinculado:

Janela do terminal
kubectl -n analytics rollout status statefulset/hitkeep
kubectl -n analytics get pods,pvc
kubectl -n analytics port-forward service/hitkeep 8080:80

Com o port-forward em execução, verifique as duas sondas em outro terminal:

Janela do terminal
curl --fail http://localhost:8080/healthz
curl --fail http://localhost:8080/readyz

/healthz confirma que o processo está ativo. /readyz confirma que o banco compartilhado e todos os bancos de tenants abertos estão prontos.

ValorPadrãoUso
image.repositoryghcr.io/pascalebeier/hitkeepRepositório da imagem do contêiner.
image.tagversão da aplicação do chart, sem v inicialSubstitua somente quando quiser executar uma imagem diferente da versão do chart.
env.HITKEEP_PUBLIC_URLhttp://localhost:8080URL visível no navegador. Defina em produção.
extraEnv[]Valores vindos de Secrets, como HITKEEP_JWT_SECRET, SMTP, S3 ou tokens de IA.
persistence.enabledtrueCria um volume claim template do StatefulSet para o diretório de dados.
persistence.mountPath/var/lib/hitkeep/dataMontagem persistente usada pelos valores padrão.
ingress.enabledfalseCria um Ingress para o controlador do cluster.
customTrackingDomains.enabledfalseConfigura domínios de rastreamento personalizados.
customTrackingDomains.ingress.enabledfalseCria um Ingress separado, somente para rastreamento, para hostnames estáticos.
service.typeClusterIPUse LoadBalancer ou NodePort apenas se corresponder ao seu cluster.
replicaCount1Defina 2 ou mais somente se quiser clustering do HitKeep.

O chart define estes caminhos, salvo substituição em env:

Variável de ambientePadrão do 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

Com esses valores, o mesmo PVC armazena banco DuckDB compartilhado, bancos DuckDB dos tenants, assets de QR Code em assets/qr-codes, arquivos e cache local opcional do filtro de spam.

O chart oferece Domínios de rastreamento personalizados sem incluir um controlador de ingress. Use o mesmo fluxo do painel: adicione o domínio nas configurações da equipe, publique o registro TXT de propriedade, aponte o DNS para o ingress e verifique quando o TLS estiver pronto.

Para controladores de ingress Kubernetes normais, use 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-tls

O chart cria um Ingress de rastreamento separado, como hitkeep-tracking, que encaminha apenas /hk.js, /hk-vitals.js, /ingest, /ingest/event e /ingest/web-vitals. Painel, API, autenticação, compartilhamento, MCP, QR e fallback da SPA não fazem parte desse Ingress. O HitKeep também impõe internamente essa separação de hosts.

Para TLS sob demanda com Caddy, implante o Caddy separadamente e mantenha o token ask em um Secret:

Janela do terminal
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: false

Configure o listener externo do Caddy com ask http://hitkeep.analytics.svc.cluster.local/internal/caddy/on-demand-tls/<token>. O Caddy envia ?domain= antes de emitir o certificado, e o HitKeep aceita somente domínios de rastreamento ativados e verificados por DNS.

Mantenha hitkeep-values.yaml sob controle de versão ou no sistema de implantação. Atualize chart e imagem juntos alterando apenas a versão do chart:

Janela do terminal
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/hitkeep

Leia as notas da versão ao atualizar entre versões com novos recursos, sobretudo ao usar integrações opcionais como MCP, configuração de IA, Google Search Console, SMTP ou backups S3.

MCP e recursos apoiados por IA ficam desativados até serem configurados. Use env para valores não sensíveis e 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-key

Consulte Servidor MCP oficial e Configuração do modelo de IA antes de ativá-los em produção.

Use este manifesto se não usar Helm. Ele mantém os caminhos de execução alinhados ao chart oficial.

Salve como 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-data
namespace: analytics
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: hitkeep-headless
namespace: analytics
spec:
clusterIP: None
publishNotReadyAddresses: true
selector:
app: hitkeep
ports:
- name: gossip-tcp
port: 7946
protocol: TCP
targetPort: gossip-tcp
- name: gossip-udp
port: 7946
protocol: UDP
targetPort: gossip-udp
---
apiVersion: v1
kind: Service
metadata:
name: hitkeep
namespace: analytics
spec:
type: ClusterIP
selector:
app: hitkeep
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: hitkeep
namespace: analytics
spec:
serviceName: hitkeep-headless
replicas: 1
selector:
matchLabels:
app: hitkeep
template:
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-data

Aplique o manifesto:

Janela do terminal
kubectl apply -f hitkeep.yaml
kubectl -n analytics rollout status statefulset/hitkeep

Adicione o Ingress ou Service externo conforme o controlador ou balanceador usado no cluster.

O HitKeep expõe dois endpoints para o Kubernetes:

EndpointFinalidade
GET /healthzIntegridade. O processo está ativo.
GET /readyzProntidão. O banco compartilhado e todos os bancos de tenants abertos estão saudáveis.

Esses endpoints permanecem disponíveis na raiz local mesmo quando HITKEEP_PUBLIC_URL contém um prefixo.

Durante a recuperação do banco, /healthz permanece bem-sucedido para que o kubelet não encerre um processo em recuperação segura. /readyz retorna 503, Retry-After: 5 e um motivo JSON, como database_recovering ou database_needs_attention, retirando o pod do serviço até que o banco esteja saudável.

Se o cluster usa nginx-ingress, Traefik ou AWS ALB, configure os CIDRs confiáveis para que IPs reais sejam usados nas análises e limites:

env:
HITKEEP_TRUSTED_PROXIES: "10.0.0.0/8"

Consulte Proxies confiáveis.

Faça backup de todo o caminho persistente. Com os valores padrão do chart e o manifesto acima, os caminhos importantes são:

  • /var/lib/hitkeep/data/hitkeep.db para dados compartilhados do plano de controle;
  • /var/lib/hitkeep/data/tenants/*/hitkeep.db para dados analíticos das equipes não padrão;
  • /var/lib/hitkeep/data/assets/qr-codes/* para os assets de QR Code;
  • /var/lib/hitkeep/data/archive para arquivos locais;
  • /var/lib/hitkeep/data/backups se HITKEEP_BACKUP_PATH usar esse caminho;
  • /var/lib/hitkeep/data/recovery para pacotes de recuperação com permissão restrita e marcadores retomáveis, salvo substituição de HITKEEP_DB_RECOVERY_PATH.

Para ativar snapshots automáticos locais no mesmo PVC:

env:
HITKEEP_BACKUP_PATH: "/var/lib/hitkeep/data/backups"
HITKEEP_BACKUP_INTERVAL: "60"
HITKEEP_BACKUP_RETENTION: "24"

Para backups fora do cluster, use um HITKEEP_BACKUP_PATH s3:// e configure as variáveis S3 em um Secret. Consulte Backups no S3.

Executa o HitKeep no Kubernetes, mas não quer administrar StatefulSets, PVCs e atualizações do cluster? O HitKeep Cloud cuida da infraestrutura na região gerenciada escolhida.