Simple and effective site analytics
I’d like to share a small but useful find in the category of simple and effective tools that handle a small yet important part of analytics work like collecting statistics for small to medium-sized websites without requiring extra effort for setup or ongoing maintenance.
Let me introduce GoatCounter — easy web analytics with no tracking of personal data. Its setup takes just a couple of minutes, and it doesn’t require large configuration files, complex databases, search engines, or ClickHouse. Just a single binary and SQLite — that’s all and its awesome.

I just wanted to say thank you to Martin Tournoij and the many developers who helped build this, and I hope my humble publication will also help promote this wonderful tool.
And just in case you need a ready-made configuration. The simplest setup ever:
# docker-compose.yaml
services:
nginx:
image: nginx:1.26-bookworm
container_name: nginx
deploy:
replicas: 1
resources:
limits:
cpus: '1'
memory: 512M
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
- /var/www/html/blog/public:/usr/share/nginx/html
ports:
- "80:80"
- "443:443"
depends_on:
- goatcounter
networks:
- backend
goatcounter:
image: arp242/goatcounter:latest
container_name: goatcounter
command: serve -automigrate
restart: always
volumes:
- goatcounter-data:/home/goatcounter/goatcounter-data
networks:
- backend
volumes:
goatcounter-data:
networks:
backend:
driver: bridge
And also Nginx configuration:
# nginx.conf
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/nginx/certs/selfsigned.crt;
ssl_certificate_key /etc/nginx/certs/selfsigned.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
location / {
proxy_pass http://goatcounter:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}