Vince is a self-hosted, open-source web analytics platform that lets you regain full control of your data.
In this guide, you’ll discover its architecture, modules, key algorithms, dependencies, configuration, and systemd integration.
By reading, you’ll learn how to deploy Vince with Docker, secure it with Let’s Encrypt, and customize dashboards.
Project Overview: Vince
Vince is a self-hosted, open-source web analytics platform that provides automatic TLS, comprehensive event tracking, and public dashboards—all in a zero-dependency Go binary. Tailored for privacy-conscious self-hosters, it delivers a lightweight, Plausible-compatible experience under the AGPL-3.0 license.
- ⚖️ Licensed under AGPL-3.0
- 🔒 Automatic TLS via Let’s Encrypt
- 📊 Plausible-compatible analytics script
- ➡️ Outbound links, file downloads, and 404 tracking
- 🔑 Public & password-protected dashboards
- 🧱 Zero dependencies: single binary
- 🌐 Unlimited sites & events
Why Vince is important for you
- Retain full data ownership and privacy control
- Simplify deployment with a single executable
- Scale without external databases or services
- Integrate seamlessly with Docker or Kubernetes
Key Concepts and Algorithms
Vince ingests raw HTTP events and stores them in per-site shards using Pebble (a high-performance LSM key-value store).
The computation engine leverages Roaring bitmaps and FlatBuffers for compact, efficient time-series and unique visitor counting. ACME autocert provides automatic TLS provisioning.
The HTTP server (built with urfave/cli
, net/http
) exposes both UI and JSON APIs for real-time analytics.
High-Level Technical Overview: Vince
- Languages: Go (backend), JavaScript/Node.js (frontend bundler & CSS), HTML/CSS.
- Structure: Organized into CLI (
internal/cmd
), storage (internal/shards
), compute, API/UI, utilities, and front-end (app
,tracker
). - Configuration: Configurable via CLI flags, environment variables (e.g.,
VINCE_DATA
,VINCE_ADMIN_NAME
), and systemd config (vince.conf
). - Environment: Run as a standalone binary, Docker container, systemd service, or on Kubernetes using Helm charts.
- Static Analysis: Go code managed with modules, linting with
go vet
; JS linted with ESLint; Protocol Buffers checked by Buf.
Module Descriptions
In case you care, this is a very high-level overview of the core components for Vince WebAn:
- internal/cmd: CLI commands (
admin
,serve
) and flag parsing. - internal/shards: Data storage abstraction using Pebble DB shards.
- internal/ops: Core operations (admin creation, event handling).
- internal/compute & internal/timeseries: Analytics computation engine processing time-series data.
- internal/api & internal/web: JSON API endpoints and HTTP handlers for the web UI.
- internal/util: Utilities for ACME, configuration, and environment management.
- internal/version: Embeds version and build timestamp.
- proto: Protocol Buffer service and message definitions (managed with Buf).
- app: Front-end assets (JavaScript, CSS, HTML templates).
- tracker: Script bundler to generate the Plausible-compatible analytics snippet.
- tools: Auxiliary tools (e.g., custom view generators).
- k8s: Kubernetes and Helm chart templates for orchestration.
Dependencies
- Go Module Dependencies (from
go.mod
):- urfave/cli/v3
- cockroachdb/pebble
- cockroachdb/swiss
- roaring
- regexp2
- flatbuffers
- uuid
- go-nanoid
- maxminddb-golang
- yaml.v2
- golang.org/x/crypto (ACME autocert)
- google.golang.org/protobuf
- JavaScript Dependencies (in
tracker/package.json
):- express
- handlebars
- uglify-js
- generatorics
- @playwright/test
- Build & Tools:
- Go 1.24 toolchain
- Node.js (for asset bundling)
- Buf (for Protocol Buffers)
- Docker (via
vince.Dockerfile
) - GitHub Actions (release workflow)
SelfHosting Vince
Vince supports deployment as a standalone binary, Docker container, systemd service, or Kubernetes.
Deploying with Docker
If you like Portainer as much as I do, just copy the stack below and you will have Vince up and running:
services:
vince:
image: ghcr.io/vinceanalytics/vince
container_name: vince #https://www.vinceanalytics.com/blog/deploy-docker/
ports:
- "8080:8080"
volumes:
- vince_data:/vince-data
#command: serve --adminName acme --adminPassword 1234 --domains vinceanalytics.com --profile
command: serve --adminName yourusername --adminPassword change1234this --domains yourdomain.com --profile #change the passwordaccordingly
restart: unless-stopped
volumes:
vince_data:
Services in docker-compose: Just one required!
- vince: The main analytics server, accessible on port 8080, persisting data in the
vince-data
volume. - It supports both architectures:
docker manifest inspect ghcr.io/vinceanalytics/vince | jq -r '.manifests[].platform.architecture' | sort -u
Architecture | Availability |
---|---|
linux/amd64 | Available ✅ |
linux/arm64 | Available ✅ |
Configuration
Vince is configured via CLI flags and environment variables:
VINCE_DATA
: Data directory (defaultvince-data
).VINCE_ADMIN_NAME
/VINCE_ADMIN_PASSWORD
: Initial admin credentials.VINCE_DOMAINS
: Comma-separated domains to register.
Once ready, you can copy your snippet to your websites:
You can also capture events:
Conclusion
Vince provides a robust yet lightweight open-source web analytics solution for self-hosters.
You can fully own your data and scale effortlessly.
Whether running as a Docker container, systemd service, or on Kubernetes, Vince fits seamlessly into your infrastructure, as it requires only ~30mb of RAM.
sudo docker stats vince
#sudo docker logs vince
Self-hosting Web Analytics alternatives to explore:
Latest Releases
The project have been maturing on this 2025 as per:
- v1.11.6: Fixed dashboard reload 404 error.
- v1.11.5: Updated dashboard assets, added Fly.io client IP header support, cleaned up referrer names, fixed domain settings link, typo corrections.
- v1.11.4: Fixed broken links on the dashboard.
- v1.11.3: Fixed admin account creation bug, updated README and demo links.
git log -1 --pretty=format:'%h %s (%ci)'
#51241b0e store resolution in columns (#57) (2025-03-16 03:17:19 +0300)
git describe --tags --abbrev=0
#v1.11.6
git tag --sort=-v:refname | head -n 5