Quartz will nicht…

Ich habe es beim ersten Versuch nicht geschafft Goatcounter bei mir einzurichten. Erst beim zweiten Versuch hat es geklappt. Dieses Mal habe ich den neuen star of the scene Deepseek bemüht – kurz gesagt: er überlegt viel ist aber auch so bockstarr wie OpenAIs o1 reasoning Modell.

Bastellösung mit eigener Component

Die Formatierung bei Typscript macht mich dezent fertig. Keine Ahnung wie da was gemacht werden muss und leider hilft die Doku von Quartz auch nicht wirklich. Oder besser gesagt, man muss sich schon entsprechend mit all diesen Frontend-Sachen auskennen, damit man der Anleitung folgen kann – oder sie gar nicht mehr braucht. Dank sehr langem herumprobieren – es ist ja auf einmal schon Februar und nicht nur mehr Jänner – hat es endlich funktioniert.

Im folgenden die Ergebnisse des Herumprobierens. Während des Prozesses habe ich halt nicht wirklich viel mitegschrieben, das wäre auch etwas langwierig geworden, aber da ich wohl dem Motto “Move fast and hudl’ things” operiere gibt es einfach die entsprechenden Code Schnippserl, welche in verschieden Configs im Projektordner quartz ihren Platz finden sollten.

So muss die Syntax in quartz.config.ts sein:

    analytics: {
      provider: 'goatcounter',
      host: 'stats.martinfellner.at',
      websiteId: 'stats.martinfellner.at',
      scriptSrc: 'https://stats.martinfellner.at/count.js'
    },

Neu erstellte GoatCounter.tsx unter /opt/quartz/quartz/components/scripts:

// quartz/components/scripts/GoatCounter.tsx
import { QuartzComponentConstructor } from "../types"

const GoatCounter = () => {
  return (
    <script
      data-goatcounter="https://stats.martinfellner.at/count"
      async
      src="https://stats.martinfellner.at/count.js"
    ></script>
  )
}

export default (() => GoatCounter) satisfies QuartzComponentConstructor

index.ts unter /opt/quartz/quartz/components:

import GoatCounter from "./scripts/GoatCounter"

{...}

  GoatCounter,

Zuletzt noch quartz.layout.ts:

// components shared across all pages
export const sharedPageComponents: SharedLayout = {
  head: Component.Head(),
  header: [],
  afterBody: [Component.GoatCounter()], //Hier ist die Component
  footer: Component.Footer({
    links: {
      GitHub: "https://github.com/jackyzha0/quartz",
      "Discord Community": "https://discord.gg/cRFFHYye7t",
    },
  }),
}

Und zu meiner Überraschung hat es sogar funktioniert!

Es geht!

Das Ergebnis…

… erlaubt einen Einblick in die enorme Leserschaft dieser Seite.

Einrichtung mit System.d Service

Ich halte mich an die Anleitung vom sehr empfehlenswerten Aplrd und diesen Blogbeitrag. Ich habe das Systemd-Modul von der zweiten Quelle adaptiert.

Mit nano /etc/systemd/system/goatcounter.service Konfig-Datei erstellen und so definieren:

# /etc/systemd/system/goatcounter.service
# Description of what the program does
[Unit]
Description=GoatCounter stats
After=network-online.target
 
[Service]
Type=simple
# If anything unexpected happens, Systemd will try to restart the program
Restart=always
# We need to send the absolute path of the database to GoatCounter.
ExecStart=/usr/bin/env goatcounter serve -db sqlite3:///opt/goatcounter/db/goatcounter.sqlite3 -listen :8080 -tls none
 
[Install]
WantedBy=multi-user.target

Starten mit systemctl start goatcounter. Wenn es funktioniert hat kann man mit systemctl status goatcounter überprüfen, ob das Modul läuft:

* goatcounter.service - GoatCounter stats
     Loaded: loaded (/etc/systemd/system/goatcounter.service; disabled; preset: enabled)
     Active: active (running) since Sat 2025-02-15 22:07:46 UTC; 5s ago
   Main PID: 20109 (goatcounter)
      Tasks: 9 (limit: 19059)
     Memory: 34.0M (peak: 34.6M)
        CPU: 381ms
     CGroup: /system.slice/goatcounter.service
             `-20109 goatcounter serve -db sqlite3:///opt/goatcounter/db/goatcounter.sqli>

Feb 15 22:07:46 goatcounter systemd[1]: Started goatcounter.service - GoatCounter stats.

Sehr schön, jetzt sollte Goatcounter auch zuverlässig laufen und automatisch beim Hochfahren des LXC Containers startet (welcher auch automatisch bei einem Hochfahren von Proxmox mitgestartet wird).