Goatcounter analytics in ikiwiki
I have started using Goatcounter for analytics after reading this LWN article called "Lightweight alternatives to Google Analytics". Goatcounter has an interesting approach to privacy in that it:
tracks sessions using a hash of the browser's user agent and IP address to identify the client without storing any personal information. The salt used to generate these hashes is rotated every 4 hours with a sliding window.
There was no Debian package for the project, so I filed a request for package and instead made a fork of the project to add a Docker image.
This page documents how Goatcounter was setup from there...
Initial server configuration
Note that this procedure was slightly modified to use docker-compose
to ease upgrades, see the upgrade procedure at the end for details.
build the image from this fork
docker build -t zgoat/goatcounter .create volume for db:
docker volume create goatcounterstart the server:
exec docker run --restart=unless-stopped --volume="goatcounter:/home/user/db/" --publish 127.0.0.1:8081:8080 --detach zgoat/goatcounter serve -listen :8080 -tls noneapache configuration:
<VirtualHost *:80> ServerName analytics.anarc.at Redirect / https://analytics.anarc.at/ DocumentRoot /var/www/html/ </VirtualHost> <VirtualHost *:443> ServerName analytics.anarc.at Use common-letsencrypt-ssl analytics.anarc.at DocumentRoot /var/www/html/ ProxyPass /.well-known/ ! ProxyPass / http://localhost:8081/ ProxyPassReverse / http://localhost:8081/ ProxyPreserveHost on </VirtualHost>add
analytics.anarc.atto DNScreate a TLS cert with LE:
certbot certonly --webroot -d analytics.anarc.at --webroot-path /var/www/html/note that goatcounter has code to do this on its own, but we avoid it to follow our existing policies and simplify things
create site:
docker run -it --rm --volume="goatcounter:/home/user/db/" zgoat/goatcounter create -domain analytics.anarc.at -email anarcat+rapports@anarc.atrebuild wiki:
ikiwiki --setup ikiwiki.setup --rebuild --verbose
Remaining issues
- Docker image should be
FROM scratch, this is statically built golang stuff after all... update: someone else made an image based on alpine, but still notFROM scratch... mine could possibly work, but I'm not sure how to create the user... or do i need aUSERto run as non-root? TBD. - this is all super janky and should be put in config management somehow
- do log parsing instead of Javascript or 1x1 images? now possible, but not deployed (yet?)
Fixed issues
cache headers are wrong (120ms!)deployed workaround in apache, reported as a bug upstreamremove self-refererdone, just a matter of configuring the URL in the settings. could this be automated too?add pixel tracking fordone, but required a patch to ikiwi (and I noticed another bug while doing it)noscriptusers(fixed upstream!)goatcounter monitordoesn't with sqlitethe :8080 port leaks in some places, namely in the "Site config" documentationthat is because i was using-port 8080which was not necessary.move to Docker Compose or podman instead of just starting the thing by handdone, although i still need to watch for releasescompare with goaccess logs, probably at the end of july, to have two full weeks to compare.done, see this post.remove "anarc.at" test site (the site is the analytics site, not the tracked site), seems like this is not possible yetfixed upstream, site marked as deletedtitles are messed up since the 2.x upgrade, see upstream bug reportdue to a database migration that normalized the tables, will fix itself eventually apparently
Upgrade procedure
This procedure was done to upgrade from ~1.4.0 to 1.4.2, 2.0.4, and 2.1.1:
rebase on top of target release
cd ~anarcat/dist/goatcounter/ git rebase v2.1.1build image:
docker build -t anarcat/goatcounter:2.1.1 .stop old container:
cd ~anarcat/src/composes/goatcounter/ docker-compose rm --stopbackup container data:
tar -c -z -C /var/lib/docker/volumes/ -f /var/lib/docker/volumes/goatcounter.tgz goatcounter_goatcounter/update the image version:
sed -i s,anarcat/goatcounter:.*,anarcat/goatcounter:2.1.1, docker-compose.ymlrun the migrations:
docker-compose run goatcounter db migrate allstart container with new image, make sure to update the
image:tag:docker-compose up -d