---
title: "HitKeep zelf hosten met Docker Compose | HitKeep"
description: "Host HitKeep zelf met Docker Compose, permanente opslag, vooraf geconfigureerde netwerken en reverse-proxyvoorbeelden voor Caddy, nginx en Traefik."
canonical: "https://hitkeep.com/nl/guides/installation/docker-compose/"
---

# HitKeep zelf hosten met Docker Compose

Docker Compose biedt een reproduceerbare, versiebeheerbare implementatie met permanente opslagvolumes. Je analysedata blijven in een benoemd Docker-volume op je server staan, inclusief de gedeelde `hitkeep.db` en tenantdatabases die onder `tenants/*/hitkeep.db` worden aangemaakt.

Deze pagina gaat over het uitvoeren van HitKeep als zelfgehoste service. Gebruik voor de hot-reload-ontwikkelomgeving met Go, Air, Angular, Mailpit en vooraf ingevulde demodata in Docker de [handleiding voor bijdragen](https://hitkeep.com/guides/contributing/).

Bij elke release worden HitKeep-images naar twee registries gepubliceerd:

| Registry | Image |
| --- | --- |
| Docker Hub | pascalebeier/hitkeep |
| GitHub Container Registry | ghcr.io/pascalebeier/hitkeep |

Beide registries bevatten identieke multiplatform-images (`linux/amd64`, `linux/arm64`) met ondertekende provenance-attestaties. Kies de registry die het beste past bij je netwerk- of pull-ratevereisten.

Houd geheimen buiten Compose-bestanden

Geef gevoelige waarden (`HITKEEP_JWT_SECRET`, SMTP-wachtwoorden) door via omgevingsvariabelen, een `.env`-bestand of Docker secrets, niet hardcoded in `compose.yml` of commandoflags. Neem `.env` niet op in versiebeheer. Gebruik Docker secrets voor strengere geheimenverwerking.

## Snel aan de slag

Een implementatie bestaat uit twee bestanden in één map: `compose.yml` (kopieer dit letterlijk; je hoeft het nooit te bewerken) en `.env` (hier staan jouw waarden). Compose vervangt bij het opstarten elke `${VARIABLE}` in `compose.yml` door de bijbehorende regel uit `.env`.

### 1. Maak compose.yml aan

Maak een map aan en voeg het volgende `compose.yml` toe. Deze basis houdt live data, het bewaararchief en automatische back-upsnapshots in afzonderlijke benoemde volumes. Ditzelfde bestand wordt in de repository onderhouden als [`examples/compose.yml`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/compose.yml), samen met [`examples/.env.example`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/.env.example), als je liever vanuit de bron kopieert.

```
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. Maak .env aan

Genereer eerst de sleutel voor sessieondertekening. Voer dit in je terminal uit en kopieer de uitvoer:

```
openssl rand -hex 32
```

Als `openssl` niet is geïnstalleerd, produceert `head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n'; echo` een gelijkwaardige waarde op elke Linux-machine.

Maak vervolgens naast `compose.yml` met je editor een bestand met de naam `.env` en vul je waarden in:

```
# 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.com
HITKEEP_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=587
HITKEEP_MAIL_USERNAME=
HITKEEP_MAIL_PASSWORD=
HITKEEP_MAIL_FROM_ADDRESS=hitkeep@localhost
HITKEEP_MAIL_FROM_NAME=HitKeep
```

.env is geen shellscript

`.env` bevat gewone regels in de vorm `KEY=value`: geen `echo`, accolades of `$(command)`-substitutie. Docker Compose leest de inhoud letterlijk, waardoor opdrachten die je in het bestand plakt ook als letterlijke tekst aankomen. Aanhalingstekens rond waarden zijn niet nodig. Houd het bestand buiten versiebeheer (voeg het toe aan `.gitignore`).

De twee bestanden gebruiken bewust een andere syntaxis: `compose.yml` is YAML, dus omgevingswaarden staan daar als `KEY: value`; `.env` gebruikt dotenv-opmaak als `KEY=value`.

### 3. Start HitKeep

```
docker compose up -d
docker compose logs -f hitkeep
```

De logregels `Starting HitKeep` en `HTTP server starting` betekenen dat de service actief is.

### 4. Meld je aan

Open `HITKEEP_PUBLIC_URL` in je browser. De installatiewizard maakt het eerste account aan, dat automatisch eigenaar van de instantie wordt, en helpt je de eerste site toe te voegen.

Het databasebestand staat in het volume `hitkeep_data`. Daardoor is ook de standaardmap voor automatisch herstel, `/var/lib/hitkeep/data/recovery`, permanent. Bewaararchieven staan in `hitkeep_archive` en automatische databasesnapshots worden naar `hitkeep_backups` geschreven. Herstelbundels bevatten databasemateriaal, vallen niet onder de rotatie van back-upretentie en moeten afzonderlijk worden beveiligd en verwijderd. MCP is beschikbaar op `/mcp`, maar clients hebben nog steeds gescope API-clientbearertokens nodig.

MCP is optioneel in het product en staat in dit Compose-voorbeeld aan voor teams die alleen-lezen toegang voor assistenten of rapportages willen. Verwijder `HITKEEP_MCP_ENABLED`, `HITKEEP_MCP_PATH` en `HITKEEP_MCP_MAX_RANGE_DAYS` als je geen MCP-endpoint wilt publiceren.

Verrijking met een AI-provider is optioneel en standaard uitgeschakeld. Laat `HITKEEP_AI_ENABLED=false` staan totdat je een provider en model hebt gekozen, inloggegevens hebt geconfigureerd en lokale budgetlimieten hebt ingesteld. Zie [Aanbevelingen voor kansen](https://hitkeep.com/guides/analytics/opportunities/) en de [handleiding voor AI-modelconfiguratie](https://hitkeep.com/guides/admin/ai-model-configuration/) voor de exacte velden.

Sociale aanmelding is optioneel. Stel voor elke gewenste provider zowel de client-ID als het clientgeheim in en registreer daarna exact de callback-URL die uit `HITKEEP_PUBLIC_URL` volgt. De [handleiding voor sociale aanmelding](https://hitkeep.com/guides/security/social-sign-in/) behandelt providerregistratie, callbackpaden, e-mailverificatie, uitnodigingen, MFA en accountkoppeling. `HITKEEP_SOCIAL_SIGNUP_ENABLED` opent geen openbare registratie op een zelfgehoste instantie.

Gegevens voor plaats-, provider- en ASN-opzoekingen zijn in de release-images ingebouwd. Runtime-Compose-implementaties hebben geen `IP2LOCATION_DOWNLOAD_TOKEN` nodig.

## Controleren

Controleer of Compose een actieve service ziet en beide runtimeprobes slagen:

```
docker compose ps
curl --fail http://localhost:8080/healthz
curl --fail http://localhost:8080/readyz
docker compose logs --since=5m hitkeep
```

`/healthz` bevestigt dat het proces actief is. `/readyz` bevestigt dat de gedeelde database en elke geopende tenantdatabase gereed zijn. Als HitKeep alleen via je reverse proxy bereikbaar is, voer de probe dan uit op de browserzichtbare URL.

## Upgraden

Lees de [nieuwste releaseopmerkingen](https://github.com/PascaleBeier/hitkeep/releases/latest) en controleer of er een actuele back-up is. Haal vervolgens de huidige stabiele image op en maak alleen de HitKeep-service opnieuw aan:

```
docker compose pull hitkeep
docker compose up -d hitkeep
docker compose ps
curl --fail http://localhost:8080/readyz
```

Compose behoudt de benoemde volumes voor data, archieven en back-ups wanneer de container wordt vervangen. Voer tijdens een upgrade geen `docker compose down -v` uit; `-v` verwijdert deze volumes.

## Reverse-proxyconfiguraties

Voer HitKeep voor productie-HTTPS achter een reverse proxy uit. Configureer [vertrouwde proxy’s](https://hitkeep.com/guides/installation/trusted-proxies/), zodat echte client-IP’s worden gebruikt voor analyse en snelheidslimieten.

`HITKEEP_PUBLIC_URL` mag een padprefix bevatten. Stel bijvoorbeeld `HITKEEP_PUBLIC_URL=https://www.example.net/hitkeep/` in wanneer HitKeep onder een bestaande site wordt gekoppeld. De proxy moet hetzelfde prefix publiceren, zoals `/hitkeep/*`, en het naar de HitKeep-container doorsturen. HitKeep biedt dan de dashboard-base-href, API-aanroepen, `hk.js`, `hk-vitals.js` en ingest-endpoints onder dat prefix aan.

- Caddy
- nginx
- Traefik

`caddy-docker-proxy` verzorgt automatische HTTPS (Let’s Encrypt) en genereert Caddy-configuratie rechtstreeks uit Docker-labels. Gebruik bij voorkeur een speciaal ingressnetwerk en vertrouw in HitKeep alleen de CIDR van dat netwerk.

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

Twee waarden komen uit je terminal: het sessiegeheim en de CIDR van het Caddy-netwerk:

```
openssl rand -hex 32
docker network inspect caddy --format '{{(index .IPAM.Config 0).Subnet}}'
```

Maak daarna met je editor het `.env`-bestand aan:

```
# Required. Paste the generated 64-character hex string here.
HITKEEP_JWT_SECRET=paste-the-generated-value-here
HITKEEP_PUBLIC_URL=https://analytics.example.com
HITKEEP_HOSTNAME=analytics.example.com
CADDY_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=common
HITKEEP_MAIL_HOST=smtp.example.com
HITKEEP_MAIL_PORT=587
HITKEEP_MAIL_USERNAME=postmaster@example.com
HITKEEP_MAIL_PASSWORD=change-me
HITKEEP_MAIL_FROM_ADDRESS=analytics@example.com
HITKEEP_MAIL_FROM_NAME=HitKeep
```

`HITKEEP_TRUSTED_PROXIES` moet de CIDR van je reverse-proxynetwerk zijn, niet `0.0.0.0/0`.

Houd bij koppeling onder een submap `HITKEEP_PUBLIC_URL` en het routeprefix van de reverse proxy gelijk. De equivalente Caddy-route is:

```
HITKEEP_PUBLIC_URL=https://www.example.net/hitkeep/
HITKEEP_HOSTNAME=www.example.net
```

```
www.example.net {
handle /hitkeep* {
  reverse_proxy hitkeep:8080
}
encode zstd gzip
}
```

Houd voor een bestaande nginx op de host, die zelf certificaten beheert, het `compose.yml` uit de snelstart aan en laat nginx naar de gepubliceerde poort verwijzen.

Pas de snelstartbestanden op twee punten aan:

1. Bind in `compose.yml` de poort aan loopback, zodat alleen de lokale nginx de container kan bereiken:

```
    ports:
    - "127.0.0.1:8080:8080"
```

1. Stel in `.env` de openbare URL in op het domein dat nginx aanbiedt en vertrouw het Docker-netwerk. Hostverkeer bereikt de container via de Docker-netwerkgateway in het bereik `172.16.0.0/12`:

```
HITKEEP_PUBLIC_URL=https://analytics.example.com
HITKEEP_TRUSTED_PROXIES=172.16.0.0/12
```

Voeg daarna een serverblok toe aan 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;
  }
}
```

Herlaad nginx (`nginx -t && systemctl reload nginx`) en open `https://analytics.example.com`. Als alle bezoekers van één privé-IP lijken te komen, controleer dan opnieuw [Vertrouwde proxy’s](https://hitkeep.com/guides/installation/trusted-proxies/).

Stel HitKeep in bestaande Traefik-stacks beschikbaar met 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: {}
```

## Aangepaste trackingdomeinen

Zelfgehoste teams kunnen [aangepaste trackingdomeinen](https://hitkeep.com/guides/tracking/custom-tracking-domains/) gebruiken met elke reverse proxy die TLS beëindigt en de oorspronkelijke `Host`-header behoudt. Gebruik de externe TLS-modus wanneer certificaten door nginx, Traefik, een load balancer of een ander ACME-proces worden beheerd. Gebruik het Caddy-profiel alleen wanneer je domeinen via het dashboard wilt inrichten met on-demand certificaatuitgifte.

### Externe TLS met nginx of Traefik

Voeg de volgende HitKeep-instellingen toe wanneer de reverse proxy certificaten al afhandelt:

```
HITKEEP_CUSTOM_TRACKING_TLS_MODE: external
```

Voeg in externe modus elke trackinghostnaam aan de proxy toe voordat het team in HitKeep op **Verify** klikt. De verificatieprobe vereist dat `https://<hostname>/hk.js` de tracker met een geldig certificaat retourneert.

De HitKeep-repository bevat voorbeelden zonder Caddy:

- [`examples/nginx.custom-tracking.conf`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/nginx.custom-tracking.conf)
- [`examples/compose.nginx-custom-tracking.yml`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/compose.nginx-custom-tracking.yml)
- [`examples/traefik.custom-tracking.yml`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/traefik.custom-tracking.yml)
- [`examples/compose.traefik-custom-tracking.yml`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/compose.traefik-custom-tracking.yml)

Het nginx-voorbeeld beperkt aangepaste trackinghosts bij de proxy tot trackerassets en ingest-routes. Het Traefik-voorbeeld gebruikt exacte `Host(...)`-items voor elke trackinghostnaam; vervang dit niet door een catch-allregel, tenzij je bewust willekeurige hostnamen wilt accepteren.

### Caddy on-demand TLS

Voeg deze HitKeep-instellingen toe aan de service `hitkeep`:

```
HITKEEP_CUSTOM_TRACKING_TLS_MODE: caddy-on-demand
HITKEEP_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:-}
```

Genereer de ask-token in je terminal (`openssl rand -hex 32`) en voeg deze als nieuwe regel toe aan `.env`:

```
HITKEEP_CADDY_TLS_ASK_TOKEN=paste-the-generated-value-here
```

Gebruik een Caddyfile met permanente opslag en een beperkt on-demand-TLS-ask-endpoint:

```
{
email ops@example.com
storage 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:8080
encode 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
}
```

Caddy stuurt `?domain=` naar de ask-URL voordat een certificaat wordt uitgegeven. HitKeep retourneert alleen `204` wanneer de token overeenkomt en de aangevraagde hostnaam een ingeschakeld, via DNS geverifieerd aangepast trackingdomein is. Voer Caddy on-demand TLS niet uit zonder `ask`; anders kan elke hostnaam die je Caddy-listener bereikt certificaatuitgifte proberen.

De HitKeep-repository bevat een compleet optioneel profiel:

- [`examples/Caddyfile.custom-tracking`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/Caddyfile.custom-tracking)
- [`examples/compose.caddy-on-demand.yml`](https://github.com/PascaleBeier/hitkeep/blob/main/examples/compose.caddy-on-demand.yml)

## Back-up

De snelstart activeert HitKeeps checkpointgebaseerde back-upworker en bewaart snapshots in het permanente volume `hitkeep_backups`. Test een herstelprocedure voordat je erop vertrouwt en kopieer back-ups van de Docker-host af, zodat een hoststoring niet zowel live data als hersteldata kan verwijderen. Zie [Back-ups en herstel](https://hitkeep.com/guides/data/backups-and-restore/) voor de volledige dataset en herstelprocedure.

### S3-compatibele back-ups of archieven gebruiken

De bovenstaande voorbeelden gebruiken lokale Docker-volumes. Vervang de lokale paden door `s3://`-URL’s en voeg de S3-instellingen toe aan `.env` om back-upsnapshots of bewaararchieven naar objectopslag te schrijven:

```
# 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/archive
HITKEEP_S3_REGION=eu-central-1
# Static credentials are optional when your container runtime provides an AWS credential chain.
HITKEEP_S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
HITKEEP_S3_SECRET_ACCESS_KEY=change-me
```

Stel voor MinIO, Cloudflare R2, Backblaze B2 of een ander S3-compatibel endpoint ook `HITKEEP_S3_ENDPOINT` in en, indien nodig, `HITKEEP_S3_URL_STYLE=path`. Zie [S3-back-ups](https://hitkeep.com/guides/data/s3-backups/) voor providerspecifieke voorbeelden.

## Problemen oplossen

**Tijdens installatie of aanmelding toont het dashboard “An unexpected error occurred”.** Doorloop deze stappen in volgorde:

1. **Lees eerst de containerlogs**: `docker compose logs hitkeep`. HitKeep logt elke serverfout op errorniveau. Blijven de logs stil terwijl de browser een fout toont, dan heeft het verzoek de container niet bereikt. Dat wijst op de reverse proxy of een onjuiste `HITKEEP_PUBLIC_URL`, niet op HitKeep.
2. **`HITKEEP_PUBLIC_URL` moet exact overeenkomen met de adresbalk**: schema, host en poort. Bij een openbare `https://`-URL krijgen sessiecookies de secure-markering en mislukt aanmelden via gewone HTTP stilzwijgend. Voer na een wijziging in `.env` opnieuw `docker compose up -d` uit; Compose past omgevingswijzigingen alleen toe wanneer de container opnieuw wordt aangemaakt.
3. **`Setup has already been completed.`** betekent dat er al een gebruiker in de database staat, meestal door een `hitkeep_data`-volume van een eerdere poging. `docker compose down -v` verwijdert de benoemde volumes en geeft je een schone start (dit verwijdert alle analysedata).
4. **E-mailinstellingen veroorzaken geen problemen tijdens de installatie.** Bij het aanmaken van het eerste account wordt geen e-mail verzonden; lege `HITKEEP_MAIL_*`-waarden blokkeren dit nooit. SMTP is pas later nodig voor uitnodigingen, wachtwoordherstel en e-mailrapporten.
5. **Meer details nodig?** Voeg `HITKEEP_LOG_LEVEL: debug` toe onder `environment:` in `compose.yml` en voer `docker compose up -d` opnieuw uit.

## Gerelateerd

- [Vertrouwde proxy’s](https://hitkeep.com/guides/installation/trusted-proxies/)
- [Sociale aanmelding](https://hitkeep.com/guides/security/social-sign-in/)
- [Aangepaste trackingdomeinen](https://hitkeep.com/guides/tracking/custom-tracking-domains/)
- [Configuratiereferentie](https://hitkeep.com/reference/configuration/)
- [Databewaring](https://hitkeep.com/guides/data/retention/)
- [S3-back-ups](https://hitkeep.com/guides/data/s3-backups/)
- [Binary-installatie](https://hitkeep.com/nl/guides/installation/binary/)

Heb je beheerde hosting met een expliciete regiokeuze nodig? [Vergelijk HitKeep Cloud](https://hitkeep.com/nl/pricing/) voor hosting in de EU (Frankfurt) of VS (Virginia) zonder zelf de container, upgrades of back-ups te beheren.

[Vorige Linux-binary](https://hitkeep.com/nl/guides/installation/binary/)[Volgende Kubernetes en Helm](https://hitkeep.com/nl/guides/installation/kubernetes/)
