I wanted a way to track the various websites I host in a privacy friendly way, so I decided on umami.is. Now, how do you set up umami on k8s?

Storage

Since I went with microk8s I decided on mayastor for persistent storage

Database

Obviously extremely overkill, but why not.. I decided to use Zalando's HA Postgres Operator for k8s: https://github.com/zalando/postgres-operator

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  labels:
    application: umami
  name: umami-psql
  namespace: umami-web
spec:
  databases:
    umami: umami
  numberOfInstances: 1
  postgresql:
    version: "15"
    parameters:  # Expert section
      huge_pages: off
  preparedDatabases:
    umami:
      defaultUsers: true
      schemas:
        data: {}
        history:
          defaultRoles: true
          defaultUsers: false
  resources:
    limits:
      cpu: 500m
      memory: 500Mi
    requests:
      cpu: 10m
      memory: 100Mi
  teamId: default
  users:
    kristian:
      - superuser
      - createdb
    umami: []
  volume:
    size: 1Gi
    storageClass: mayastor-2

Umami

Now to the part the blog post is actually about. This my deployment for Umami. I have annotation for keel which will automatically update umami daily.

This assumed your cluster is called umami-psql. Make sure to replace this with your actual postgres cluster name. In this case I called the initial DB umami.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: umami-web
  namespace: umami-web
  annotations:
    keel.sh/policy: force
    keel.sh/pollSchedule: '@every 24h'
    keel.sh/trigger: poll
spec:
  replicas: 2
  selector:
    matchLabels:
      app: umami-web
  template:
    metadata:
      labels:
        app: umami-web
    spec:
      containers:
        - name: web
          image: ghcr.io/umami-software/umami:postgresql-latest
          ports:
            - containerPort: 5000
              protocol: TCP
          env:
            - name: PORT
              value: '5000'
            - name: DB_DATABASE
              value: "umami"
            - name: DB_HOST
              value: '$(UMAMI_PSQL_SERVICE_HOST)'
            - name: DB_PORT
              value: '$(UMAMI_PSQL_SERVICE_PORT_POSTGRESQL)'
            - name: DB_USERNAME
              valueFrom:
                secretKeyRef:
                  name: umami.umami-psql.credentials.postgresql.acid.zalan.do
                  key: username
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: umami.umami-psql.credentials.postgresql.acid.zalan.do
                  key: password
            - name: DATABASE_URL
              value: "postgres://$(DB_USERNAME):$(DB_PASSWORD)@$(DB_HOST):$(DB_PORT)/$(DB_DATABASE)"
          imagePullPolicy: Always