Docker Compose
Docker Compose gives you a reproducible, version-controlled deployment with persistent storage volumes — your analytics data stays in a named Docker volume on your server, backed by the hitkeep.db file inside it.
HitKeep images are published to two registries on every release:
| Registry | Image |
|---|---|
| Docker Hub | pascalebeier/hitkeep |
| GitHub Container Registry | ghcr.io/pascalebeier/hitkeep |
Both registries carry identical, multi-platform images (linux/amd64, linux/arm64) with signed provenance attestations. Use whichever registry suits your network or pull-rate requirements.
Quick Start
Section titled “Quick Start”Create a compose.yml:
services: hitkeep: # Also available as: ghcr.io/pascalebeier/hitkeep:latest 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 environment: - HITKEEP_JWT_SECRET=${HITKEEP_JWT_SECRET} command: - "-public-url=http://localhost:8080" - "-archive-path=/var/lib/hitkeep/archive"
volumes: hitkeep_data: {} hitkeep_archive: {}Create a .env file alongside it (add to .gitignore):
HITKEEP_JWT_SECRET=$(openssl rand -hex 32)Start it:
docker compose up -ddocker compose logs -f hitkeepThe database file lives inside the hitkeep_data volume. Back it up by copying the file out of the volume or using docker cp.
Reverse Proxy Configurations
Section titled “Reverse Proxy Configurations”Run HitKeep behind a reverse proxy for production HTTPS. Configure Trusted Proxies so real client IPs are used for analytics and rate limiting.
Caddy handles automatic HTTPS (Let’s Encrypt) with zero certificate management.
services: caddy: image: caddy:latest restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" volumes: - caddy_data:/data - caddy_config:/config - ./Caddyfile:/etc/caddy/Caddyfile networks: - hitkeep_net
hitkeep: image: pascalebeier/hitkeep:latest restart: unless-stopped networks: - hitkeep_net volumes: - hitkeep_data:/var/lib/hitkeep/data - hitkeep_archive:/var/lib/hitkeep/archive environment: - HITKEEP_JWT_SECRET=${HITKEEP_JWT_SECRET} command: - "-public-url=https://analytics.example.com" - "-trusted-proxies=172.16.0.0/12" - "-archive-path=/var/lib/hitkeep/archive"
volumes: caddy_data: {} caddy_config: {} hitkeep_data: {} hitkeep_archive: {}
networks: hitkeep_net:Caddyfile:
analytics.example.com { reverse_proxy hitkeep:8080}For existing Traefik stacks, expose HitKeep with labels:
services: hitkeep: image: pascalebeier/hitkeep:latest restart: unless-stopped volumes: - hitkeep_data:/var/lib/hitkeep/data - hitkeep_archive:/var/lib/hitkeep/archive environment: - HITKEEP_JWT_SECRET=${HITKEEP_JWT_SECRET} command: - "-public-url=https://analytics.example.com" - "-trusted-proxies=172.16.0.0/12" - "-archive-path=/var/lib/hitkeep/archive" 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: {}Related
Section titled “Related”Need managed hosting without giving up data sovereignty? HitKeep Cloud → runs the same Docker image in your chosen sovereign region — EU (Frankfurt, GDPR) or US (Virginia).