Hospedar o HitKeep com Docker Compose
O Docker Compose oferece uma implantação reproduzível e versionada com volumes de armazenamento persistente. Seus dados analíticos permanecem em um volume Docker nomeado no servidor, incluindo o hitkeep.db compartilhado e os bancos locais de tenants em tenants/*/hitkeep.db.
Esta página ensina a executar o HitKeep como serviço self-hosted. Para o ambiente de contribuição com hot reload, Go, Air, Angular, Mailpit e dados de demonstração no Docker, consulte o guia de contribuição.
As imagens do HitKeep são publicadas em dois registros a cada versão:
| Registro | Imagem |
|---|---|
| Docker Hub | pascalebeier/hitkeep |
| GitHub Container Registry | ghcr.io/pascalebeier/hitkeep |
Os dois registros contêm as mesmas imagens multiplataforma (linux/amd64, linux/arm64), com attestations de procedência assinadas. Use o registro mais adequado à sua rede ou aos limites de download.
Início rápido
Seção intitulada “Início rápido”A implantação usa dois arquivos no mesmo diretório: compose.yml (copie sem alterar) e .env (onde ficam os seus valores). Ao iniciar, o Compose substitui cada ${VARIABLE} de compose.yml pela linha correspondente de .env.
1. Criar compose.yml
Seção intitulada “1. Criar compose.yml”Crie um diretório e adicione este compose.yml. A configuração base mantém dados ativos, arquivos de retenção e snapshots automáticos em volumes nomeados separados. O mesmo arquivo é mantido no repositório como examples/compose.yml, junto de examples/.env.example.
services: hitkeep: image: pascalebeier/hitkeep:latest container_name: hitkeep restart: unless-stopped ports: - "8080:8080" volumes: - hitkeep_data:/var/lib/hitkeep/data - hitkeep_archive:/var/lib/hitkeep/archive - hitkeep_backups:/var/lib/hitkeep/backups environment: # Public URL must match the browser-visible origin, including any path prefix. HITKEEP_PUBLIC_URL: ${HITKEEP_PUBLIC_URL:-http://localhost:8080} # Required for stable sessions. Generate with: openssl rand -hex 32 HITKEEP_JWT_SECRET: ${HITKEEP_JWT_SECRET:?set HITKEEP_JWT_SECRET in .env} # Behind a reverse proxy, set to the proxy network CIDR so real client IPs are used. HITKEEP_TRUSTED_PROXIES: ${HITKEEP_TRUSTED_PROXIES:-} # config-default-override: require an explicit trusted proxy network # Keep live data, retention archives, and backup snapshots on persistent volumes. HITKEEP_DB_PATH: /var/lib/hitkeep/data/hitkeep.db HITKEEP_DATA_PATH: /var/lib/hitkeep/data HITKEEP_ARCHIVE_PATH: /var/lib/hitkeep/archive HITKEEP_BACKUP_PATH: /var/lib/hitkeep/backups HITKEEP_BACKUP_INTERVAL: ${HITKEEP_BACKUP_INTERVAL:-60} HITKEEP_BACKUP_RETENTION: ${HITKEEP_BACKUP_RETENTION:-24} # Optional OSS spam-list refresh. Disable for fully offline/air-gapped installs. HITKEEP_SPAM_FILTER_AUTO_UPDATE: "true" HITKEEP_SPAM_FILTER_UPDATE_INTERVAL: ${HITKEEP_SPAM_FILTER_UPDATE_INTERVAL:-1440} HITKEEP_SPAM_FILTER_PATH: /var/lib/hitkeep/data/spam-filter.json # Optional read-only MCP endpoint for governed assistant/reporting access. HITKEEP_MCP_ENABLED: "true" HITKEEP_MCP_PATH: /mcp HITKEEP_MCP_MAX_RANGE_DAYS: ${HITKEEP_MCP_MAX_RANGE_DAYS:-366} # Optional AI model route for Opportunity enrichment. Provider credentials # use the selected goAI provider's own env vars, such as OPENAI_API_KEY. HITKEEP_AI_ENABLED: ${HITKEEP_AI_ENABLED:-false} HITKEEP_AI_PROVIDER: ${HITKEEP_AI_PROVIDER:-} HITKEEP_AI_MODEL: ${HITKEEP_AI_MODEL:-} HITKEEP_AI_BASE_URL: ${HITKEEP_AI_BASE_URL:-} HITKEEP_AI_REGION: ${HITKEEP_AI_REGION:-} HITKEEP_AI_API_KEY: ${HITKEEP_AI_API_KEY:-} HITKEEP_AI_REQUEST_LIMIT: ${HITKEEP_AI_REQUEST_LIMIT:-100} HITKEEP_AI_TOKEN_LIMIT: ${HITKEEP_AI_TOKEN_LIMIT:-100000} HITKEEP_AI_BUDGET_WINDOW: ${HITKEEP_AI_BUDGET_WINDOW:-1440} # Optional Google Search Console OAuth integration. HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_ID: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_ID:-} HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET:-} HITKEEP_GOOGLE_SEARCH_CONSOLE_REDIRECT_URL: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_REDIRECT_URL:-} # Optional Google, GitHub, and Microsoft social sign-in. HITKEEP_SOCIAL_GOOGLE_CLIENT_ID: ${HITKEEP_SOCIAL_GOOGLE_CLIENT_ID:-} HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET: ${HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET:-} HITKEEP_SOCIAL_GITHUB_CLIENT_ID: ${HITKEEP_SOCIAL_GITHUB_CLIENT_ID:-} HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET: ${HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET:-} HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID: ${HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID:-} HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET: ${HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET:-} HITKEEP_SOCIAL_MICROSOFT_TENANT: ${HITKEEP_SOCIAL_MICROSOFT_TENANT:-common} # SMTP powers invites, password reset, email reports, and security mail. HITKEEP_MAIL_HOST: ${HITKEEP_MAIL_HOST:-} HITKEEP_MAIL_PORT: ${HITKEEP_MAIL_PORT:-587} HITKEEP_MAIL_USERNAME: ${HITKEEP_MAIL_USERNAME:-} HITKEEP_MAIL_PASSWORD: ${HITKEEP_MAIL_PASSWORD:-} HITKEEP_MAIL_ENCRYPTION: ${HITKEEP_MAIL_ENCRYPTION:-tls} HITKEEP_MAIL_FROM_ADDRESS: ${HITKEEP_MAIL_FROM_ADDRESS:-hitkeep@localhost} HITKEEP_MAIL_FROM_NAME: ${HITKEEP_MAIL_FROM_NAME:-HitKeep}
volumes: hitkeep_data: {} hitkeep_archive: {} hitkeep_backups: {}2. Criar .env
Seção intitulada “2. Criar .env”Primeiro, gere a chave de assinatura da sessão no terminal e copie o resultado:
openssl rand -hex 32Se openssl não estiver instalado, head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n'; echo gera um valor equivalente em qualquer máquina Linux.
Em seguida, crie no editor um arquivo .env ao lado de compose.yml e preencha os valores:
# Required. Paste the generated 64-character hex string here.HITKEEP_JWT_SECRET=paste-the-generated-value-here# Required. The exact URL you open in the browser. Behind a reverse proxy# this is your public domain, e.g. https://analytics.example.comHITKEEP_PUBLIC_URL=http://localhost:8080# Optional social sign-in. Set both values for each provider you enable.HITKEEP_SOCIAL_GOOGLE_CLIENT_ID=HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET=HITKEEP_SOCIAL_GITHUB_CLIENT_ID=HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET=HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID=HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET=HITKEEP_SOCIAL_MICROSOFT_TENANT=common# Optional SMTP. Powers invites, password resets, and email reports.# Leave the values empty to run without outbound mail.HITKEEP_MAIL_HOST=HITKEEP_MAIL_PORT=587HITKEEP_MAIL_USERNAME=HITKEEP_MAIL_PASSWORD=HITKEEP_MAIL_FROM_ADDRESS=hitkeep@localhostHITKEEP_MAIL_FROM_NAME=HitKeep3. Iniciar o HitKeep
Seção intitulada “3. Iniciar o HitKeep”docker compose up -ddocker compose logs -f hitkeepAs linhas Starting HitKeep e HTTP server starting indicam que o serviço está no ar.
4. Entrar
Seção intitulada “4. Entrar”Abra HITKEEP_PUBLIC_URL no navegador. O assistente cria a primeira conta, que se torna automaticamente proprietária da instância, e orienta você a adicionar o primeiro site.
O banco fica no volume hitkeep_data. O diretório padrão de recuperação automática, /var/lib/hitkeep/data/recovery, também é persistente. Arquivos de retenção ficam em hitkeep_archive, e snapshots automáticos em hitkeep_backups. Pacotes de recuperação contêm material do banco, não seguem a retenção dos backups e devem ser protegidos e removidos separadamente. O MCP é exposto em /mcp, mas clientes ainda precisam de tokens bearer de API com escopo.
O MCP é opcional no produto e está ativado neste exemplo para equipes que desejam acesso somente leitura por assistentes e relatórios. Remova HITKEEP_MCP_ENABLED, HITKEEP_MCP_PATH e HITKEEP_MCP_MAX_RANGE_DAYS se não for publicar um endpoint MCP.
O enriquecimento por provedor de IA é opcional e fica desativado por padrão. Mantenha HITKEEP_AI_ENABLED=false até escolher provedor e modelo, configurar credenciais e limites locais de orçamento. Consulte Recomendações de oportunidades e o guia de configuração do modelo de IA.
O login social é opcional. Defina o ID e o segredo de cada provedor desejado e registre a callback exata derivada de HITKEEP_PUBLIC_URL. O guia de login social cobre cadastro dos provedores, callbacks, verificação de e-mail, convites, MFA e vinculação de contas. HITKEEP_SOCIAL_SIGNUP_ENABLED não abre cadastro público em uma instância self-hosted.
Dados de cidade, provedor e ASN estão incorporados às imagens. Implantações Compose não precisam de IP2LOCATION_DOWNLOAD_TOKEN em execução.
Verificar
Seção intitulada “Verificar”Confirme que o serviço está em execução e que as duas sondas respondem:
docker compose pscurl --fail http://localhost:8080/healthzcurl --fail http://localhost:8080/readyzdocker compose logs --since=5m hitkeep/healthz confirma que o processo está ativo. /readyz confirma que o banco compartilhado e todos os bancos de tenants abertos estão prontos. Se o HitKeep só estiver acessível pelo proxy reverso, use a URL visível no navegador.
Atualizar
Seção intitulada “Atualizar”Leia as notas da versão mais recente e confirme que existe um backup atual. Baixe a imagem estável e recrie apenas o serviço do HitKeep:
docker compose pull hitkeepdocker compose up -d hitkeepdocker compose pscurl --fail http://localhost:8080/readyzO Compose mantém os volumes de dados, arquivos e backups ao substituir o contêiner. Não execute docker compose down -v durante a atualização: -v exclui esses volumes.
Configurações de proxy reverso
Seção intitulada “Configurações de proxy reverso”Em produção, execute o HitKeep atrás de um proxy reverso com HTTPS. Configure os proxies confiáveis para usar os IPs reais nas análises e nos limites de requisições.
HITKEEP_PUBLIC_URL pode conter um prefixo. Por exemplo, use HITKEEP_PUBLIC_URL=https://www.example.net/hitkeep/ para montar o HitKeep abaixo de outro site. O proxy deve publicar o mesmo prefixo, como /hitkeep/*, e encaminhá-lo ao contêiner. Assim, base do painel, API, hk.js, hk-vitals.js e endpoints de ingestão permanecem nesse prefixo.
O caddy-docker-proxy oferece HTTPS automático (Let’s Encrypt) e gera a configuração do Caddy a partir dos labels do Docker.
A prática recomendada é usar uma rede de ingress dedicada e confiar somente no CIDR dessa rede.
services:caddy: image: lucaslorentz/caddy-docker-proxy:2.9-alpine container_name: caddy-proxy restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" environment: CADDY_INGRESS_NETWORKS: caddy volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - caddy_data:/data - caddy_config:/config networks: - caddy labels: caddy.email: ${CADDY_EMAIL:?set in .env}
hitkeep: image: pascalebeier/hitkeep:latest container_name: hitkeep restart: unless-stopped networks: - caddy volumes: - hitkeep_data:/var/lib/hitkeep/data - hitkeep_archive:/var/lib/hitkeep/archive - hitkeep_backups:/var/lib/hitkeep/backups environment: HITKEEP_NODE_NAME: leader # Public URL must match the HTTPS origin served by Caddy, including any path prefix. HITKEEP_PUBLIC_URL: ${HITKEEP_PUBLIC_URL:?set in .env} # Required for stable sessions. Generate with: openssl rand -hex 32 HITKEEP_JWT_SECRET: ${HITKEEP_JWT_SECRET:?set in .env} # Must be the Caddy network CIDR. This controls real visitor IP, geo/network metadata, # country exclusions, rate limiting, and spam checks. HITKEEP_TRUSTED_PROXIES: ${HITKEEP_TRUSTED_PROXIES:?set to your caddy network CIDR} # Keep live data, retention archives, and backup snapshots on persistent volumes. HITKEEP_DB_PATH: /var/lib/hitkeep/data/hitkeep.db HITKEEP_DATA_PATH: /var/lib/hitkeep/data HITKEEP_ARCHIVE_PATH: /var/lib/hitkeep/archive HITKEEP_BACKUP_PATH: /var/lib/hitkeep/backups HITKEEP_BACKUP_INTERVAL: ${HITKEEP_BACKUP_INTERVAL:-60} HITKEEP_BACKUP_RETENTION: ${HITKEEP_BACKUP_RETENTION:-24} # Optional OSS spam-list refresh. Disable for fully offline/air-gapped installs. HITKEEP_SPAM_FILTER_AUTO_UPDATE: "true" HITKEEP_SPAM_FILTER_UPDATE_INTERVAL: ${HITKEEP_SPAM_FILTER_UPDATE_INTERVAL:-1440} HITKEEP_SPAM_FILTER_PATH: /var/lib/hitkeep/data/spam-filter.json # Optional read-only MCP endpoint for governed assistant/reporting access. HITKEEP_MCP_ENABLED: "true" HITKEEP_MCP_PATH: /mcp HITKEEP_MCP_MAX_RANGE_DAYS: ${HITKEEP_MCP_MAX_RANGE_DAYS:-366} # Optional AI model route for Opportunity enrichment. Leave disabled until a provider is configured. HITKEEP_AI_ENABLED: ${HITKEEP_AI_ENABLED:-false} HITKEEP_AI_PROVIDER: ${HITKEEP_AI_PROVIDER:-} HITKEEP_AI_MODEL: ${HITKEEP_AI_MODEL:-} HITKEEP_AI_BASE_URL: ${HITKEEP_AI_BASE_URL:-} HITKEEP_AI_REGION: ${HITKEEP_AI_REGION:-} HITKEEP_AI_API_KEY: ${HITKEEP_AI_API_KEY:-} HITKEEP_AI_REQUEST_LIMIT: ${HITKEEP_AI_REQUEST_LIMIT:-100} HITKEEP_AI_TOKEN_LIMIT: ${HITKEEP_AI_TOKEN_LIMIT:-100000} HITKEEP_AI_BUDGET_WINDOW: ${HITKEEP_AI_BUDGET_WINDOW:-1440} # Optional Google Search Console OAuth integration. HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_ID: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_ID:-} HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET:-} HITKEEP_GOOGLE_SEARCH_CONSOLE_REDIRECT_URL: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_REDIRECT_URL:-} # Optional Google, GitHub, and Microsoft social sign-in. HITKEEP_SOCIAL_GOOGLE_CLIENT_ID: ${HITKEEP_SOCIAL_GOOGLE_CLIENT_ID:-} HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET: ${HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET:-} HITKEEP_SOCIAL_GITHUB_CLIENT_ID: ${HITKEEP_SOCIAL_GITHUB_CLIENT_ID:-} HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET: ${HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET:-} HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID: ${HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID:-} HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET: ${HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET:-} HITKEEP_SOCIAL_MICROSOFT_TENANT: ${HITKEEP_SOCIAL_MICROSOFT_TENANT:-common} # SMTP powers invites, password reset, email reports, and security mail. HITKEEP_MAIL_HOST: ${HITKEEP_MAIL_HOST:-} HITKEEP_MAIL_PORT: ${HITKEEP_MAIL_PORT:-587} HITKEEP_MAIL_USERNAME: ${HITKEEP_MAIL_USERNAME:-} HITKEEP_MAIL_PASSWORD: ${HITKEEP_MAIL_PASSWORD:-} HITKEEP_MAIL_ENCRYPTION: ${HITKEEP_MAIL_ENCRYPTION:-tls} HITKEEP_MAIL_FROM_ADDRESS: ${HITKEEP_MAIL_FROM_ADDRESS:-hitkeep@localhost} HITKEEP_MAIL_FROM_NAME: ${HITKEEP_MAIL_FROM_NAME:-HitKeep} labels: caddy: ${HITKEEP_HOSTNAME:?set in .env} caddy.reverse_proxy: "{{upstreams 8080}}" caddy.encode: "zstd gzip"
volumes:caddy_data: {}caddy_config: {}hitkeep_data: {}hitkeep_archive: {}hitkeep_backups: {}
networks:caddy: external: trueDois valores vêm do terminal: o segredo da sessão e o CIDR da rede do Caddy:
openssl rand -hex 32docker network inspect caddy --format '{{(index .IPAM.Config 0).Subnet}}'Depois, crie o arquivo .env no editor:
# Required. Paste the generated 64-character hex string here.HITKEEP_JWT_SECRET=paste-the-generated-value-hereHITKEEP_PUBLIC_URL=https://analytics.example.comHITKEEP_HOSTNAME=analytics.example.comCADDY_EMAIL=ops@example.com# Paste the Caddy network subnet from the docker network inspect command.HITKEEP_TRUSTED_PROXIES=paste-the-caddy-subnet-here# Optional social sign-in. Set both values for each provider you enable.HITKEEP_SOCIAL_GOOGLE_CLIENT_ID=HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET=HITKEEP_SOCIAL_GITHUB_CLIENT_ID=HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET=HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID=HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET=HITKEEP_SOCIAL_MICROSOFT_TENANT=commonHITKEEP_MAIL_HOST=smtp.example.comHITKEEP_MAIL_PORT=587HITKEEP_MAIL_USERNAME=postmaster@example.comHITKEEP_MAIL_PASSWORD=change-meHITKEEP_MAIL_FROM_ADDRESS=analytics@example.comHITKEEP_MAIL_FROM_NAME=HitKeepHITKEEP_TRUSTED_PROXIES deve ser o CIDR da rede do proxy reverso, não 0.0.0.0/0.
Para uma montagem em subdiretório, mantenha HITKEEP_PUBLIC_URL e o prefixo da rota do proxy alinhados. A rota equivalente no Caddy é:
HITKEEP_PUBLIC_URL=https://www.example.net/hitkeep/HITKEEP_HOSTNAME=www.example.netwww.example.net {handle /hitkeep* { reverse_proxy hitkeep:8080}encode zstd gzip}Para um nginx existente no host, que administra seus próprios certificados (por exemplo, via certbot), mantenha o compose.yml do início rápido e aponte o nginx para a porta publicada.
Faça dois ajustes nos arquivos:
- Em
compose.yml, vincule a porta ao loopback para que apenas o nginx local alcance o contêiner:
ports: - "127.0.0.1:8080:8080"- Em
.env, defina a URL pública com o domínio do nginx e confie na rede Docker. O tráfego do host chega pelo gateway Docker, na faixa172.16.0.0/12:
HITKEEP_PUBLIC_URL=https://analytics.example.comHITKEEP_TRUSTED_PROXIES=172.16.0.0/12Depois, adicione um bloco de servidor ao nginx:
server { listen 443 ssl; http2 on; server_name analytics.example.com;
# ssl_certificate / ssl_certificate_key as issued by certbot or your CA.
location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; # Live dashboard updates stream over server-sent events. proxy_set_header Connection ""; proxy_buffering off; proxy_read_timeout 300s; }}Recarregue o nginx (nginx -t && systemctl reload nginx) e abra https://analytics.example.com. Se todos os visitantes aparecerem com o mesmo IP privado, reveja Proxies confiáveis.
Em stacks existentes com Traefik, exponha o HitKeep com labels:
services:hitkeep: image: pascalebeier/hitkeep:latest restart: unless-stopped volumes: - hitkeep_data:/var/lib/hitkeep/data - hitkeep_archive:/var/lib/hitkeep/archive - hitkeep_backups:/var/lib/hitkeep/backups environment: # Public URL must match the HTTPS origin served by Traefik, including any path prefix. HITKEEP_PUBLIC_URL: ${HITKEEP_PUBLIC_URL:?set in .env} # Required for stable sessions. Generate with: openssl rand -hex 32 HITKEEP_JWT_SECRET: ${HITKEEP_JWT_SECRET:?set in .env} # Must be the Traefik network CIDR. This controls real visitor IP, geo/network metadata, # country exclusions, rate limiting, and spam checks. HITKEEP_TRUSTED_PROXIES: ${HITKEEP_TRUSTED_PROXIES:?set to your traefik network CIDR} # Keep live data, retention archives, and backup snapshots on persistent volumes. HITKEEP_DB_PATH: /var/lib/hitkeep/data/hitkeep.db HITKEEP_DATA_PATH: /var/lib/hitkeep/data HITKEEP_ARCHIVE_PATH: /var/lib/hitkeep/archive HITKEEP_BACKUP_PATH: /var/lib/hitkeep/backups HITKEEP_BACKUP_INTERVAL: ${HITKEEP_BACKUP_INTERVAL:-60} HITKEEP_BACKUP_RETENTION: ${HITKEEP_BACKUP_RETENTION:-24} # Optional OSS spam-list refresh. Disable for fully offline/air-gapped installs. HITKEEP_SPAM_FILTER_AUTO_UPDATE: "true" HITKEEP_SPAM_FILTER_UPDATE_INTERVAL: ${HITKEEP_SPAM_FILTER_UPDATE_INTERVAL:-1440} HITKEEP_SPAM_FILTER_PATH: /var/lib/hitkeep/data/spam-filter.json # Optional read-only MCP endpoint for governed assistant/reporting access. HITKEEP_MCP_ENABLED: "true" HITKEEP_MCP_PATH: /mcp HITKEEP_MCP_MAX_RANGE_DAYS: ${HITKEEP_MCP_MAX_RANGE_DAYS:-366} # Optional AI model route for Opportunity enrichment. Leave disabled until a provider is configured. HITKEEP_AI_ENABLED: ${HITKEEP_AI_ENABLED:-false} HITKEEP_AI_PROVIDER: ${HITKEEP_AI_PROVIDER:-} HITKEEP_AI_MODEL: ${HITKEEP_AI_MODEL:-} HITKEEP_AI_BASE_URL: ${HITKEEP_AI_BASE_URL:-} HITKEEP_AI_REGION: ${HITKEEP_AI_REGION:-} HITKEEP_AI_API_KEY: ${HITKEEP_AI_API_KEY:-} HITKEEP_AI_REQUEST_LIMIT: ${HITKEEP_AI_REQUEST_LIMIT:-100} HITKEEP_AI_TOKEN_LIMIT: ${HITKEEP_AI_TOKEN_LIMIT:-100000} HITKEEP_AI_BUDGET_WINDOW: ${HITKEEP_AI_BUDGET_WINDOW:-1440} # Optional Google Search Console OAuth integration. HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_ID: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_ID:-} HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET:-} HITKEEP_GOOGLE_SEARCH_CONSOLE_REDIRECT_URL: ${HITKEEP_GOOGLE_SEARCH_CONSOLE_REDIRECT_URL:-} # Optional Google, GitHub, and Microsoft social sign-in. HITKEEP_SOCIAL_GOOGLE_CLIENT_ID: ${HITKEEP_SOCIAL_GOOGLE_CLIENT_ID:-} HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET: ${HITKEEP_SOCIAL_GOOGLE_CLIENT_SECRET:-} HITKEEP_SOCIAL_GITHUB_CLIENT_ID: ${HITKEEP_SOCIAL_GITHUB_CLIENT_ID:-} HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET: ${HITKEEP_SOCIAL_GITHUB_CLIENT_SECRET:-} HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID: ${HITKEEP_SOCIAL_MICROSOFT_CLIENT_ID:-} HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET: ${HITKEEP_SOCIAL_MICROSOFT_CLIENT_SECRET:-} HITKEEP_SOCIAL_MICROSOFT_TENANT: ${HITKEEP_SOCIAL_MICROSOFT_TENANT:-common} # SMTP powers invites, password reset, email reports, and security mail. HITKEEP_MAIL_HOST: ${HITKEEP_MAIL_HOST:-} HITKEEP_MAIL_PORT: ${HITKEEP_MAIL_PORT:-587} HITKEEP_MAIL_USERNAME: ${HITKEEP_MAIL_USERNAME:-} HITKEEP_MAIL_PASSWORD: ${HITKEEP_MAIL_PASSWORD:-} HITKEEP_MAIL_ENCRYPTION: ${HITKEEP_MAIL_ENCRYPTION:-tls} HITKEEP_MAIL_FROM_ADDRESS: ${HITKEEP_MAIL_FROM_ADDRESS:-hitkeep@localhost} HITKEEP_MAIL_FROM_NAME: ${HITKEEP_MAIL_FROM_NAME:-HitKeep} labels: - "traefik.enable=true" - "traefik.http.routers.hitkeep.rule=Host(`analytics.example.com`)" - "traefik.http.routers.hitkeep.entrypoints=websecure" - "traefik.http.routers.hitkeep.tls.certresolver=myresolver" - "traefik.http.services.hitkeep.loadbalancer.server.port=8080"
volumes:hitkeep_data: {}hitkeep_archive: {}hitkeep_backups: {}Domínios de rastreamento personalizados
Seção intitulada “Domínios de rastreamento personalizados”Equipes self-hosted podem usar Domínios de rastreamento personalizados com qualquer proxy reverso que encerre TLS e preserve o cabeçalho Host original. Use o modo TLS externo quando os certificados forem administrados por nginx, Traefik, balanceador ou outro processo ACME. Use o perfil do Caddy apenas para provisionamento pelo painel com certificados sob demanda.
TLS externo com nginx ou Traefik
Seção intitulada “TLS externo com nginx ou Traefik”Adicione esta configuração quando o proxy já administra os certificados:
HITKEEP_CUSTOM_TRACKING_TLS_MODE: externalNo modo externo, adicione cada hostname ao proxy antes de clicar em Verificar no HitKeep. A sonda exige que https://<hostname>/hk.js retorne o tracker com um certificado válido.
O repositório inclui exemplos sem Caddy:
examples/nginx.custom-tracking.confexamples/compose.nginx-custom-tracking.ymlexamples/traefik.custom-tracking.ymlexamples/compose.traefik-custom-tracking.yml
O exemplo nginx restringe hosts de rastreamento aos assets do tracker e às rotas de ingestão. O Traefik usa entradas Host(...) exatas; não as substitua por uma regra genérica, a menos que queira aceitar hostnames arbitrários.
TLS sob demanda com Caddy
Seção intitulada “TLS sob demanda com Caddy”Adicione ao serviço hitkeep:
HITKEEP_CUSTOM_TRACKING_TLS_MODE: caddy-on-demandHITKEEP_CADDY_TLS_ASK_TOKEN: ${HITKEEP_CADDY_TLS_ASK_TOKEN:?set in .env}# Optional. Use only when tracker hostnames point somewhere other than# the host in HITKEEP_PUBLIC_URL.HITKEEP_CUSTOM_TRACKING_DNS_TARGET: ${HITKEEP_CUSTOM_TRACKING_DNS_TARGET:-}Gere o token no terminal (openssl rand -hex 32) e adicione-o ao .env:
HITKEEP_CADDY_TLS_ASK_TOKEN=paste-the-generated-value-hereUse um Caddyfile com armazenamento persistente e endpoint ask restrito:
{email ops@example.comstorage file_system { root /data}on_demand_tls { ask http://hitkeep:8080/internal/caddy/on-demand-tls/{$HITKEEP_CADDY_TLS_ASK_TOKEN}}}
{$HITKEEP_HOSTNAME} {reverse_proxy hitkeep:8080encode zstd gzip}
https:// {tls { on_demand}
reverse_proxy hitkeep:8080 { header_up Host {host} header_up X-Forwarded-Host {host} header_up X-Forwarded-Proto {scheme}}
encode zstd gzip}O Caddy envia ?domain= ao endpoint ask antes de emitir o certificado. O HitKeep retorna 204 somente quando o token coincide e o hostname solicitado é um domínio de rastreamento ativado e verificado por DNS. Nunca use TLS sob demanda sem ask; qualquer hostname que alcance o listener poderia tentar emitir um certificado.
O repositório contém um perfil opcional completo:
O início rápido ativa o worker de backup com checkpoints e salva snapshots no volume persistente hitkeep_backups. Teste uma restauração, copie os backups para fora do host Docker e consulte Backups e restauração para o conjunto de dados completo.
Usar backups ou arquivos compatíveis com S3
Seção intitulada “Usar backups ou arquivos compatíveis com S3”Para gravar snapshots ou arquivos de retenção em armazenamento de objetos, troque os caminhos locais por URLs s3:// e adicione ao .env:
# Local or S3 backup snapshots. Empty HITKEEP_BACKUP_PATH disables automatic backups.HITKEEP_BACKUP_PATH=s3://my-analytics-bucket/hitkeep/backups# Retention archives can use local paths or S3-compatible URLs.HITKEEP_ARCHIVE_PATH=s3://my-analytics-bucket/hitkeep/archiveHITKEEP_S3_REGION=eu-central-1# Static credentials are optional when your container runtime provides an AWS credential chain.HITKEEP_S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLEHITKEEP_S3_SECRET_ACCESS_KEY=change-mePara MinIO, Cloudflare R2, Backblaze B2 ou outro endpoint compatível, defina também HITKEEP_S3_ENDPOINT e, quando necessário, HITKEEP_S3_URL_STYLE=path. Consulte Backups no S3.
Solução de problemas
Seção intitulada “Solução de problemas”O painel mostra “An unexpected error occurred” durante a configuração ou o login. Verifique nesta ordem:
- Leia primeiro os logs:
docker compose logs hitkeep. O HitKeep registra falhas do servidor no nível error. Se o navegador mostra erro, mas o log permanece vazio, a requisição não chegou ao contêiner: verifique o proxy eHITKEEP_PUBLIC_URL. HITKEEP_PUBLIC_URLdeve corresponder exatamente à barra de endereços, incluindo protocolo, host e porta. Com uma URLhttps://, os cookies são seguros e o login por HTTP falha. Depois de alterar.env, executedocker compose up -dpara recriar o contêiner.Setup has already been completed.indica que já existe usuário no banco, geralmente em um volumehitkeep_dataantigo.docker compose down -vcria um início limpo, mas exclui todos os dados analíticos.- Configurações de e-mail não bloqueiam a configuração inicial. A primeira conta não envia e-mail. SMTP só importa depois para convites, redefinição de senha e relatórios.
- Precisa de mais detalhes? Adicione
HITKEEP_LOG_LEVEL: debugemenvironment:e executedocker compose up -dnovamente.
Relacionados
Seção intitulada “Relacionados”- Proxies confiáveis
- Login social
- Domínios de rastreamento personalizados
- Referência de configuração
- Retenção de dados
- Backups no S3
- Instalação pelo binário
Precisa de hospedagem gerenciada com escolha de região? Compare o HitKeep Cloud para hospedagem na UE (Frankfurt) ou nos EUA (Virgínia), sem administrar contêiner, atualizações ou backups.