---
title: "Implantar o HitKeep no Kubernetes com Helm | HitKeep"
description: "Implante o HitKeep no Kubernetes com o chart oficial do Helm ou um StatefulSet, mantendo dados do DuckDB, assets de QR Code, arquivos e backups em armazenamento persistente."
canonical: "https://hitkeep.com/pt/guides/installation/kubernetes/"
---

# 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.

## Início rápido

### Instalar com Helm

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

```
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:

```
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:

```
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.

## Verificar

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

```
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:

```
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.

## Valores do chart que você deve revisar

| Valor | Padrão | Uso |
| --- | --- | --- |
| image.repository | ghcr.io/pascalebeier/hitkeep | Repositório da imagem do contêiner. |
| image.tag | versão da aplicação do chart, sem v inicial | Substitua somente quando quiser executar uma imagem diferente da versão do chart. |
| env.HITKEEP_PUBLIC_URL | http://localhost:8080 | URL visível no navegador. Defina em produção. |
| extraEnv | [] | Valores vindos de Secrets, como HITKEEP_JWT_SECRET, SMTP, S3 ou tokens de IA. |
| persistence.enabled | true | Cria um volume claim template do StatefulSet para o diretório de dados. |
| persistence.mountPath | /var/lib/hitkeep/data | Montagem persistente usada pelos valores padrão. |
| ingress.enabled | false | Cria um Ingress para o controlador do cluster. |
| customTrackingDomains.enabled | false | Configura domínios de rastreamento personalizados. |
| customTrackingDomains.ingress.enabled | false | Cria um Ingress separado, somente para rastreamento, para hostnames estáticos. |
| service.type | ClusterIP | Use LoadBalancer ou NodePort apenas se corresponder ao seu cluster. |
| replicaCount | 1 | Defina 2 ou mais somente se quiser clustering do HitKeep. |

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

| Variável de ambiente | Padrã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.

## Domínios de rastreamento personalizados

O chart oferece [Domínios de rastreamento personalizados](https://hitkeep.com/guides/tracking/custom-tracking-domains/) 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:

```
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.

## Atualizar

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:

```
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.

## Configuração opcional de MCP e IA

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](https://hitkeep.com/guides/integrations/mcp/) e [Configuração do modelo de IA](https://hitkeep.com/guides/admin/ai-model-configuration/) antes de ativá-los em produção.

## Manifesto Kubernetes simples

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:

```
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.

## Sondas de integridade e prontidão

O HitKeep expõe dois endpoints para o Kubernetes:

| Endpoint | Finalidade |
| --- | --- |
| GET /healthz | Integridade. O processo está ativo. |
| GET /readyz | Prontidã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.

## Proxies confiáveis

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](https://hitkeep.com/guides/installation/trusted-proxies/).

## Backup

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](https://hitkeep.com/guides/data/s3-backups/).

## Relacionados

- [Instalação com Docker Compose](https://hitkeep.com/pt/guides/installation/docker-compose/)
- [Proxies confiáveis](https://hitkeep.com/guides/installation/trusted-proxies/)
- [Backups e restauração](https://hitkeep.com/guides/data/backups-and-restore/)
- [Backups no S3](https://hitkeep.com/guides/data/s3-backups/)
- [Referência de configuração](https://hitkeep.com/reference/configuration/)
- [Arquitetura](https://hitkeep.com/reference/architecture/)

Executa o HitKeep no Kubernetes, mas não quer administrar StatefulSets, PVCs e atualizações do cluster? O [HitKeep Cloud](https://hitkeep.com/pt/pricing/) cuida da infraestrutura na região gerenciada escolhida.

[Anterior Docker Compose](https://hitkeep.com/pt/guides/installation/docker-compose/)[Próximo Trusted proxies](https://hitkeep.com/pt/guides/installation/trusted-proxies/)
