Skip to content

Persistant storage with localstorage and longhorn

See k3s storage docs for more documentation.

Below we will show two options. Local storage and distributed storage. That just means using the local storage on the node where it is running. On a single machine this is of course not a problem, but it can cause problems if you have a permanent failure of a node in a cluster, where you of course will suffer data loss. On a distributed storage on the other hand, you can make sure that the data is replicated on multiple nodes, and in that case a single node failure would be no problem.

Local storage

Local storage PVC

cat pvc-ghost-localstorage.yaml | envsubst | kubectl apply -f -
pvc-ghost-localstorage.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ghost-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 2Gi

Ghost with persistant local storage

cat ghost-localstorage.yaml | envsubst | kubectl apply -f -
ghost-localstorage.yaml
apiVersion: v1
kind: Service
metadata:
  name: ghost
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 2368
  selector:
    app: ghost
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ghost
spec:
  selector:
    matchLabels:
      app: ghost
  replicas: 1
  template:
    metadata:
      labels:
        app: ghost
    spec:
      containers:
        - name: ghost
          image: ghost:5.32.0
          # prettier-ignore
          env:
          - name: database__client
            value: sqlite3
          - name: database__connection__filename
            value: content/data/ghost.db
          - name: database__useNullAsDefault
            value: "true"
          - name: database__debug
            value: "false"
          ports:
            - containerPort: 2368
          volumeMounts:
            - name: my-ghost-volume
              mountPath: /var/lib/ghost/content
      volumes:
        - name: my-ghost-volume
          persistentVolumeClaim:
            claimName: ghost-pvc
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ghost-ingress
  annotations:
    spec.ingressClassName: traefik
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  rules:
    - host: ghost.${DOMAIN}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ghost
                port:
                  number: 80
  tls:
    - secretName: ghost-tls
      hosts:
        - ghost.${DOMAIN}

Distributed storage (Longhorn)

Setting up Longhorn

Apply the longhorn.yaml to install Longhorn

kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.0/deploy/longhorn.yaml

Longhorn will be installed in the namespace longhorn-system.

Longhorn PVC

cat pvc-ghost-longhorn.yaml | envsubst | kubectl apply -f -
pvc-ghost-longhorn.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ghost-longhorn-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn
  resources:
    requests:
      storage: 2Gi

Ghost with Longhorn distributed storage

  • first delete ghost
cat ghost-localstorage.yaml | envsubst | kubectl delete -f -
  • And then recreate it with longhorn
cat ghost-longhorn.yaml | envsubst | kubectl apply -f -

Longhorn UI

cat longhorn-ui-ingress.yaml | envsubst | kubectl apply -f -
longhorn-ui-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: longhorn-ingress
  namespace: longhorn-system
  annotations:
    spec.ingressClassName: traefik
    cert-manager.io/cluster-issuer: letsencrypt-prod
    traefik.ingress.kubernetes.io/router.middlewares: default-my-basic-auth@kubernetescrd

spec:
  rules:
  - host: longhorn.${DOMAIN}
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: longhorn-frontend
            port:
              number: 80
  tls:
    - secretName: longhorn-tls
      hosts:
        - longhorn.${DOMAIN}

Your longhorn UI should now be accessible at https://longhorn.dog.example.com Longhorn UI