Je recherchais depuis quelques temps un outils permettant de calculer et stocker les stats des visites sur mon site. Le plus connu en libre est semble t-il piwik devenu matomo mais la lourdeur de PHP/mysql me rebutait. J’ai tendance à privilégier autant que possible des services en Go, léger et rapide, avec une base sqlite.
Ca tombe bien puisque j’ai découvert fathom qui répond exactement à ce “cahier des charges”.
La page github du projet propose un lien vers leur image docker cependant nul présence d’une image pour ARM64… C’est le moment de se retrousser les manches.
La première étape est de git clone le projet puis d’adapter leur Dockerfile pour une cible ARM64 :
cat Dockerfile.arm64v8
FROM arm64v8/node:alpine AS assetbuilder
WORKDIR /app
COPY package*.json ./
COPY gulpfile.js ./
COPY assets/ ./assets/
RUN npm install && NODE_ENV=production ./node_modules/gulp/bin/gulp.js
FROM arm64v8/golang:alpine AS binarybuilder
RUN apk add -U --no-cache git build-base
RUN go get -u github.com/gobuffalo/packr/packr
WORKDIR /go/src/github.com/usefathom/fathom
COPY . /go/src/github.com/usefathom/fathom
COPY --from=assetbuilder /app/assets/build ./assets/build
COPY Makefile.arm64v8 ./
RUN make -f Makefile.arm64v8 docker
FROM arm64v8/alpine:latest
EXPOSE 8080
HEALTHCHECK --retries=10 CMD ["wget", "-qO-", "http://localhost:8080/health"]
RUN apk add --update --no-cache bash ca-certificates
WORKDIR /app
COPY --from=binarybuilder /go/src/github.com/usefathom/fathom/fathom .
CMD ["./fathom", "server"]
A noter que le Dockerfile d’origine lance un make qui utilise ce Makefile, or celui-ci force l’architecture cible en AMD64 :
GOARCH=amd64
J’ai donc copié ce fichier vers un Makefile.arm64v8 où la cible est GOARCH=arm64. Ne pas oublier de faire un COPY de ce nouveau fichier vers le conteneur : COPY Makefile.arm64v8 ./
On peut ensuite lancer un build sur une machine ARM64 :
docker build -f Dockerfile.arm64v8 -t fredix/arm64v8-fathom:latest
--build-arg http_proxy="http://fredix:PASS@192.168.254.10:3128"
--build-arg https_proxy="http://fredix:PASS@192.168.254.10:3128" .
les options –build-arg sont nécessaire sur mon infra pour permettre à Docker de sortir vers Internet via un proxy squid. Pour rappel un serveur qui n’a pas d’IP publique chez scaleway ne peut pas sortir vers Internet.
puis
docker push fredix/arm64v8-fathom:latest
Mon image est disponible sur le Docker hub : https://hub.docker.com/r/fredix/arm64v8-fathom
On peut maintenant l’instancier dans le docker swarm :
docker service create --name fathom --constraint 'node.labels.location == cloud-arm64'
--network traefik-net --label traefik.frontend.rule=Host:fathom.fredix.xyz
--label traefik.docker.network=traefik-net --label traefik.port=8080
--label traefik.backend=fathom fredix/arm64v8-fathom:latest
docker service rm fathom
Tel quel fathom va utiliser une base sqlite, mais elle sera stockée dans le conteneur dans /app/fathom.db, or je veux la stocker dans glusterfs. Sur un noeud gluster faire :
mkdir /swarm/volumes/fathom
touch /swarm/volumes/fathom/fathom.db
on peut maintenant lancer le service avec les options de montage qui vont bien
docker service create --name fathom --constraint 'node.labels.location == cloud-arm64'
--network traefik-net --label traefik.frontend.rule=Host:fathom.fredix.xyz
--label traefik.docker.network=traefik-net --label traefik.port=8080
--label traefik.backend=fathom
--mount type=bind,source=/swarm/volumes/fathom/fathom.db,target=/app/fathom.db
fredix/arm64v8-fathom:latest
Pour info on ne map pas /app mais directement /app/fathom.db car le binaire fathom se trouve dans /app. Si on map comme ceci
--mount type=bind,source=/swarm/volumes/fathom,target=/app
/app sera vide dans le conteneur puisqu’il correspondra à celui du serveur hote qui n’a pas le binaire fathom. Le service ne pourrait donc pas démarrer.
Le service est lancé mais attention par défaut l’interface web est publique. Il est nécessaire de créer un utilisateur avec un login/pass. Pour cela il faut savoir sur quel noeud du swarm est lancé le conteneur
docker service ps fathom
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
snp83agcyeps fathom.1 fredix/arm64v8-fathom:latest proxy Running Running 18 hours ago
On se connecte sur le noeud proxy puis un docker ps indique le conteneur ID de fathom
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eeb508f7fd11 fredix/arm64v8-fathom:latest "./fathom server" 18 hours ago Up 18 hours (healthy) 8080/tcp fathom.1.snp83agcyeps9pv56f4yj5nzl
On peut alors créer l’utilisateur
docker exec eeb508f7fd11 ./fathom user add --email="fredix@protonmail.com" --password="PASS"
L’interface web est maintenant vérouillée comme on peut le constater sur mon instance https://fathom.fredix.xyz/.
Une fois connecté l’interface propose de saisir le nom de domaine de son site web afin de générer le javascript à intégrer dans les pages. Ce javascript devra être inséré dans la balise <head></head>
. Pour Hugo il suffit de créer un fichier partial dans le thème utilisé
cat themes/blackburn/layouts/partials/fathom.html
<!-- Fathom - simple website analytics - https://github.com/usefathom/fathom -->
<script>
(function(f, a, t, h, o, m){
a[h]=a[h]||function(){
(a[h].q=a[h].q||[]).push(arguments)
};
o=f.createElement('script'),
m=f.getElementsByTagName('script')[0];
o.async=1; o.src=t; o.id='fathom-script';
m.parentNode.insertBefore(o,m)
})(document, window, '//fathom.fredix.xyz/tracker.js', 'fathom');
fathom('set', 'siteId', 'MELRX');
fathom('trackPageview');
</script>
<!-- / Fathom -->
puis d’ajouter ce partial dans le partial head.html
cat themes/blackburn/layouts/partials/head.html
...
{{ partial "fathom.html" . }}
</head>
Après un déploiement les premières stats arrivent
l’interface est plutôt sobre et efficace, même si ce n’est pas aussi complet qu’un matomo c’est largement suffisant. Voir la live demo.
Sources :
https://schaper.io/2018/07/using-fathom-with-postgres-and-docker/
https://www.dwastudio.fr/article/analysez-les-donnees-de-votre-site-simplement-avec-fathom/