Tracking blog readers with OxiTraffic

I recently stumbled upon OxiTraffic, a self-hosted, simple and privacy respecting website traffic tracker which is well suited for blogs. What that means is

  • No personal data is logged
  • one binary or simple docker container
  • Readers are only counted if they spend >20s per site

As I currently have no analytics on my blog and I am not inclined to use anything that adds more than 2 sentences to my privacy disclaimer I thought I give it a try. Naturally I wrote an ansible role for this, which can be found under mother-of-all-self-hosting/ansible-role-oxitraffic. I now have this neat graph.

A screenshot of OxiTraffic that shows low readership on

As the main prupose of a blog is to describe how to host the blog, I’ll continue in this tradition and describe my process below.

The Ansible Role & Playbook Integration

The ansible role is pretty simple so I won’t go into detail. It set’s up the configuration file based on your environment variables and sensible defaults and adds a labels file for traefik to use later. The systemd service that starts the container ensures it runs read-only and as non-root user (which worked out of the box, kudos to the developer).

The mash-playbook integration is wiring the OxiTraffic to the Traefik reverse proxy and the Postgres database.

After running just install-all everything was set up*.

* Actually I found a bug which was fixed very fast

Hugo Theme Integration

I maintain a fork of the hugo-nederburg-theme by Appernetic and naturally wanted to include it there. Adding the following to themes/hugo-nederburg-theme/layouts/partials/head.html is all I needed

{{ with .Site.Params.oxitraffic_url }}
  <script src="{{ . }}" defer></script>
{{ end }}

I could then make us of this by setting the Oxitraffic URL in the theme settings

  slogan = "Blog of Julian-Samuel Gebühr"
  description = "Blog of Julian-Samuel Gebühr" # meta description
  oxitraffic_url = ""

And that was it. You can have a look at the traffic of this blog at

Advanced: Setting up multiple sites in on one MASH host

You might have multiple sites that need tracking, but an instance of OxiTraffic can only monitor one site. Setting up multiple instances of OxiTraffic is more complicated in MASH, but can be done. Here is how (always replace s3 and other with you own names):

  1. Re-Do your Inventory as described in running-multiple-instances. I’ll use s3 as my “main” host here and s3.other as new host.

  2. Add the following in inventory/host_vars/s3.other

mash_playbook_generic_secret_key: 'LONGSECRET'

mash_playbook_service_identifier_prefix: 'mash-other-'
mash_playbook_service_base_directory_name_prefix: 'other-'

# OXITRAFFIC configuration
oxitraffic_enabled: true

oxitraffic_database_hostname: mash-postgres
oxitraffic_database_port: 5432
oxitraffic_database_name: other-oxitraffic
oxitraffic_database_password: VERYSECRET
oxitraffic_database_username: other-oxitraffic

oxitraffic_systemd_required_services_list: |

oxitraffic_container_additional_networks: |

oxitraffic_container_labels_traefik_enabled: "true"
oxitraffic_container_labels_traefik_docker_network: "traefik"
oxitraffic_container_labels_traefik_entrypoints: "web-secure"
oxitraffic_container_labels_traefik_tls_certResolver: "default"
  1. Create the database

Unlike for other mash services th database will not be created automatically. You therefore need to set it up yourself. Here are the steps that you need to run in the postgres CLI (which cou can access by running /mash/postgres/bin/cli)

  • Create a user: CREATE USER "other-oxitraffic" with ENCRYPTED PASSWORD 'PASSWORD_FROM_ABOVE';
  • Create database: CREATE DATABASE other-oxitraffic;
  • Grant privileges: GRANT ALL PRIVILEGES ON DATABASE "other-oxitraffic" TO "other-oxitraffic";
  • Grant ownership: ALTER DATABASE "other-oxitraffic" OWNER TO "other-oxitraffic";

Student of Medical Informatics, Developer, He/Him