---
title: "Tracking blog readers with OxiTraffic"
date: 2023-11-10T12:10:10+02:00
draft: false
image: "uploads/oxitraffic.png"
categrories: ['English']
tags: ['MASH', 'tracking', 'privacy', 'ansible', 'docker', hugo]
---
I recently stumbled upon [OxiTraffic](https://codeberg.org/mo8it/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](https://github.com/mother-of-all-self-hosting/ansible-role-oxitraffic). I now have this neat graph.

![A screenshot of OxiTraffic that shows low readership on hyteck.de](oxitraffic_screenshot.jpeg)

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](https://github.com/mother-of-all-self-hosting/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](https://codeberg.org/mo8it/oxitraffic/issues/7)

# Hugo Theme Integration

I maintain a fork of the [hugo-nederburg-theme](https://github.com/moan0s/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
```html
{{ 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

```toml
[params]
  slogan = "Blog of Julian-Samuel Gebühr"
  description = "Blog of Julian-Samuel Gebühr" # meta description
  [...]
  oxitraffic_url = "https://traffic.hyteck.de/count.js"
```

And that was it. You can have a look at the traffic of this blog at [traffic.hyteck.de](https://traffic.hyteck.de).

# 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](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/running-multiple-instances.md#re-do-your-inventory-to-add-supplementary-hosts). 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`

```yaml
# PLAYBOOK STUFF
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_hostname: traffic.other-service.de
oxitraffic_tracked_origin: https://other-service.de

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: |
  {{
    (['docker.service'])
    +
    (['mash-postgres.service'])
  }}

oxitraffic_container_additional_networks: |
  {{
    (['traefik'])
    +
    (['mash-postgres'])
  }}

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"
```

3. 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";`
