Skip to content

Plausible analytics

Create a security key

export PLAUSIBLE_SECRET_KEY_BASE=$(openssl rand -base64 64 | tr -d '\n' ; echo)

Set the other variables (please replace them as appropriate for you)

export PLAUSIBLE_POSTGRES_USER=mypostgresuser && \
export PLAUSIBLE_POSTGRES_PASSWORD=mypostgrespassword && \
export PLAUSIBLE_ADMIN_USER_EMAIL=my@email.com && \
export PLAUSIBLE_ADMIN_USER_NAME=myadminusername && \
export PLAUSIBLE_ADMIN_USER_PWD=mysecretadminpassword

Apply the manifest with envsubst

cat plausible-localstorage.yaml | envsubst | kubectl apply -f -
plausible-localstorage.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: plausible-clickhouse-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: plausible-postgres-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
  name: plausible-postgres
spec:
  type: ClusterIP
  ports:
    - port: 5432
      targetPort: 5432
  selector:
    app: plausible-postgres
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: plausible-postgres
spec:
  selector:
    matchLabels:
      app: plausible-postgres
  replicas: 1
  template:
    metadata:
      labels:
        app: plausible-postgres
    spec:
      containers:
        - name: plausible-postgres
          image: postgres:13
          env:
            - name: POSTGRES_USER
              value: ${PLAUSIBLE_POSTGRES_USER}
            - name: POSTGRES_PASSWORD
              value: ${PLAUSIBLE_POSTGRES_PASSWORD}
            - name: POSTGRES_DB
              value: "plausible_dev"
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: plausible-postgres-volume
              mountPath: /var/lib/postgresql/data
      volumes:
        - name: plausible-postgres-volume
          persistentVolumeClaim:
            claimName: plausible-postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: plausible-mail
spec:
  type: ClusterIP
  ports:
    - port: 25
      targetPort: 25
  selector:
    app: plausible-mail
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: plausible-mail
spec:
  selector:
    matchLabels:
      app: plausible-mail
  replicas: 1
  template:
    metadata:
      labels:
        app: plausible-mail
    spec:
      containers:
        - name: plausible-mail
          image: bytemark/smtp:latest
          ports:
            - containerPort: 25
---
apiVersion: v1
kind: Service
metadata:
  name: plausible-clickhouse
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 8123
  selector:
    app: plausible-clickhouse
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: plausible-clickhouse
spec:
  selector:
    matchLabels:
      app: plausible-clickhouse
  replicas: 1
  template:
    metadata:
      labels:
        app: plausible-clickhouse
    spec:
      containers:
        - name: plausible-clickhouse
          image: yandex/clickhouse-server:21.3.2.5
          volumeMounts:
            - name: plausible-clickhouse-volume
              mountPath: /var/lib/clickhouse
            - name: plausible-clickhouse-config
              mountPath: /etc/clickhouse-server/config.d/logging.xml
              subPath: logging.xml
              readOnly: true
            - name: plausible-clickhouse-user-config
              mountPath: /etc/clickhouse-server/users.d/logging.xml
              subPath: logging.xml
              readOnly: true
      volumes:
        - name: plausible-clickhouse-volume
          persistentVolumeClaim:
            claimName: plausible-clickhouse-pvc
        - name: plausible-clickhouse-config
          configMap:
            name: plausible-clickhouse-config
        - name: plausible-clickhouse-user-config
          configMap:
            name: plausible-clickhouse-user-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: plausible-clickhouse-config
data:
  logging.xml: |
    <yandex>
        <logger>
            <level>warning</level>
            <console>true</console>
        </logger>

        <!-- Stop all the unnecessary logging -->
        <query_thread_log remove="remove"/>
        <query_log remove="remove"/>
        <text_log remove="remove"/>
        <trace_log remove="remove"/>
        <metric_log remove="remove"/>
        <asynchronous_metric_log remove="remove"/>
    </yandex>
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: plausible-clickhouse-user-config
data:
  logging.xml: |
    <yandex>
        <profiles>
            <default>
                <log_queries>0</log_queries>
                <log_query_threads>0</log_query_threads>
            </default>
        </profiles>
    </yandex>
---
apiVersion: v1
kind: Service
metadata:
  name: plausible
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8000
  selector:
    app: plausible
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: plausible
spec:
  selector:
    matchLabels:
      app: plausible
  replicas: 1
  template:
    metadata:
      labels:
        app: plausible
    spec:
      containers:
        - name: plausible
          image: plausible/analytics:v1.4.4
          command: ["/bin/sh"]
          args:
            [
              "-c",
              "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run",
            ]
          ports:
            - containerPort: 8000
          env:
            - name: ADMIN_USER_EMAIL
              value: ${PLAUSIBLE_ADMIN_USER_EMAIL}
            - name: ADMIN_USER_NAME
              value: ${PLAUSIBLE_ADMIN_USER_NAME}
            - name: ADMIN_USER_PWD
              value: ${PLAUSIBLE_ADMIN_USER_PWD}
            - name: BASE_URL
              value: https://plausible.${DOMAIN}
            - name: SECRET_KEY_BASE
              value: ${PLAUSIBLE_SECRET_KEY_BASE}
            - name: DATABASE_URL
              value: postgres://${PLAUSIBLE_POSTGRES_USER}:${PLAUSIBLE_POSTGRES_PASSWORD}@plausible-postgres:5432/plausible_dev
            - name: CLICKHOUSE_DATABASE_URL
              value: http://plausible-clickhouse:8123/plausible_dev
            - name: SMTP_HOST_ADDR
              value: plausible-mail
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: plausible-ingress
  annotations:
    spec.ingressClassName: traefik
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  rules:
    - host: plausible.${DOMAIN}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: plausible
                port:
                  number: 80

This should result in something like this:

persistentvolumeclaim/plausible-clickhouse-pvc created
persistentvolumeclaim/plausible-postgres-pvc created
service/plausible-postgres created
deployment.apps/plausible-postgres created
service/plausible-mail created
deployment.apps/plausible-mail created
service/plausible-clickhouse created
deployment.apps/plausible-clickhouse created
configmap/plausible-clickhouse-config created
configmap/plausible-clickhouse-user-config created
service/plausible created
deployment.apps/plausible created
ingress.networking.k8s.io/plausible-ingress created

And your plausible instance should now be accessible at https://plausible.dog.example.com Plausible