Some might say, Google is some kind of villain. Not only because of the company’s privacy-invading tactics or the use of cookies. But did you ever try to find a key metric in the Analytics-Dashboard? Its easy to sink hours and hours into their »properties« or »key-value-pairs« or whatever they name the Json-Datapoints next. So we went to look for alternatives. And – spoiler alert: we found something …

Plausible Heroes #

Unlike Google, our hero is called Plausible. Plausible is privacy-friendly, lightweight and yes: open-source. But it gets even better: like our website, Plausible does not use cookies. The tool is also compliant with applicable data protection regulations such as GDPR, CCPA and PECR. Plausible’s servers are located in the EU. But best of all, Plausible allows us to operate our own statistics server. There’s also a dark mode. So it ticks all the right boxes. And that’s not a generic catchphrase made up by an AI. It. Is. True.

Why doesn’t everyone use this? #

Because installing and maintaining a statistics server means work, of course. But work on the part of the administrator. With Google, on the other hand, the work lies with the users.

How cool is this? #

So cool:

Plausibles übersichtliches Dashboard Plausibles übersichtliches Dashboard
The Plausible Dashboard

I want to host this myself #

Okay. That’s why we’ve put together a little bit of information on how to do this. However, this requires a little basic knowledge of containers. So if you have experience with Docker or Kubernetes and you download images from Github as if it were an app store for server stories, then you’ve come to the right place.

Note
We use Kubernetes as our container orchestrator. That’s why we’ll just go into that here. Deployments are a bit easier for Docker anyway.

Installation #

In general, Plausible consists of three containers. The database that stores the values of the individual websites is a Clickhouse cluster. The settings of the Plausible dashboard, on the other hand, are stored in a Postgres database. And last but not least, there is the Plausible container itself. It is connected to the two databases and has a fourth, optional container that is responsible for weekly mails.

Clickhouse Deployment #

Our Clickhouse installation looks roughly like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: clickhouse
  namespace: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: clickhouse
  template:
    metadata:
      labels:
        app: clickhouse
    spec:
      containers:
        - name: clickhouse
          image: clickhouse/clickhouse-server:24.12.2.29-alpine
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 8123
          envFrom:
            - secretRef:
                name: clickhouse-secret
          volumeMounts:
            - mountPath: /var/lib/clickhouse
              name: plausible-clickhouse-data
          resources:
            limits:
              cpu: 600m
              memory: 4Gi
            requests:
              cpu: 300m
              memory: 2Gi
      volumes:
        - name: plausible-clickhouse-data
          persistentVolumeClaim:
            claimName: plausible-clickhouse-data 

The database must persist data, i.e. write it permanently to a hard drive. To do this, we have created a so-called PV with the name plausible-clickhouse-data. We link this to the container. The database also needs a user and passwords. In Kubernetes, it is common practice to store access data in secrets. Our secret is therefore a file containing the following information:

apiVersion: v1
kind: Secret
metadata:
    name: clickhouse-secret
    namespace: web
type: Opaque
stringData:
    CLICKHOUSE_DB: plausible_events_db
    CLICKHOUSE_USER: username
    CLICKHOUSE_PASSWORD: password

The secret is linked to the Clickhouse container via an environment variable. We specify another service so that Plausible can access the statistics database, i.e. Clickhouse:

apiVersion: v1
kind: Service
metadata:
  name: clickhouse
  namespace: web
  labels:
    app: clickhouse
spec:
  ports:
    - port: 8123
  selector:
    app: clickhouse

The port number 8123 is specified in the container and in the service. And that is actually the entire installation of Clickhouse.

Plausible Deployment #

Our deployment for Plausible itself looks like this:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: plausible
  namespace: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: plausible
  template:
    metadata:
      labels:
        app: plausible
    spec:
      - name: plausible-migrate
        image: ghcr.io/plausible/community-edition:v2.1.5
        command:
          - '/bin/sh'
          - '-c'
        args:
          # Uncomment first line for initial deployment and then switch
          # - 'sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run'
          # - '/entrypoint.sh db migrate'
        envFrom:
          - secretRef:
              name: plausible-config
      containers:
        - name: plausible
          image: ghcr.io/plausible/community-edition:v2.1.5
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 8000
          envFrom: 
          - secretRef:
              name: plausible-config
        - name: mail
          image: bytemark/smtp
          imagePullPolicy: "IfNotPresent"
          envFrom:
          - secretRef:
              name: plausible-config

The database must be created during the initial installation. Therefore you give the container the command 'sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run'. However, this is only necessary for the initial installation. After you have created the database, you can delete the previous command and instead enter: '/entrypoint.sh db migrate'.

The last lines in the manifest describe the mail container, which uses bytemark/smtp as the image. It is optional and can also be omitted. In this case, you will not have the option of sending weekly update mails automatically.

Our two Plausible containers also require various settings and credentials. The secret file looks like this:

apiVersion: v1
kind: Secret
metadata:
    name: plausible-config
    namespace: web
type: Opaque
stringData:
    CLICKHOUSE_DATABASE_URL: http://username:password@clickhouse.web.svc.cluster.local:8123/plausible_events_db
    DATABASE_URL: postgresql://plausible:password@postgres.web.svc.cluster.local/plausible
    BASE_URL: https://statistics.example.com
    SMTP_HOST_ADDR: smtp.example.com
    SMTP_HOST_PORT: "587"
    CRON_ENABLED: "true"
    LOG_LEVEL: info
    DISABLE_REGISTRATION: invite_only
    ENABLE_EMAIL_VERIFICATION: "true"
    TOTP_VAULT_KEY: abc12345678912345678912345678912345678912345
    MAILER_EMAIL: hello@example.com
    MAILER_NAME: Hello
    SMTP_USER_PWD: password
    SMTP_USER_NAME: user@example.com

With CLICKHOUSE_DATABASE_URL we tell Plausible where to find the Clickhouse database. DATABASE_URL is the same for the Postgres database. Base-Url corresponds to the Url where your statistics server should be accessible. You set CRON_ENABLED to true so that the server can perform recurring tasks, such as a weekly info mail. Then add a few passwords - including for your mail server - and you’re done.

Now we just need a service that points to port 8000 so that you can access the Plausible app via the browser. In our case, the service looks like this:

apiVersion: v1
kind: Service
metadata:
  name: plausible
  namespace: web
  labels:
    app: plausible
spec:
  ports:
    - port: 8000
  selector:
    app: plausible

Postgres Deployment #

You have several options for deploying Postgres. However, you probably already have the database running in your stack anyway. If not, we recommend using the Bitnami deployment. With or without a helmet. You can find out exactly how to do this here.

Test #

Your statistics server should now be accessible under the IP address of your server on port 8000, i.e. http://192.168.1.2:8000.

Branding #

Plausible also offers the option of integrating the dashboard on your own site without branding. How great is this? So great.

Note
Of course, we know that many people choose to keep their website statistics secret. But we at Lightwaves stand for radical transparency. That’s why we share our website statistics with you. Perhaps you have a suitable way for us to improve our bounce rate.😚

Outro #

Okay. To be honest, it’s a bit of work to set up a statistics server like this. But yes. At Lightwaves, you can simply add Plausible to your website package. Then we take care of the complicated installation and maintenance. And you’ll have the most privacy-friendly analytics server in the world.

That is why we vote for Plausible - your users will appreciate it too.