Nextcloud

Prerequisites

This guide assumes you have the following prerequisites in place:

Nextcloud

Nextcloud is an open-source, self-hosted file sharing and collaboration platform. I will be deploying collabora online with nextcloud to enable online document editing.

Installation

  1. Create the following directory structure for Nextcloud:
  nextcloud/
  ├── collabora.yml
  ├── nextcloud-db.yml
  ├── nextcloud-ingress.yml
  ├── nextcloud-pvc.yml
  ├── nextcloud-secret.yml
  ├── nextcloud-svc.yml
  └── nextcloud.yml
  1. Add the following content to collabora.yml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: collabora
  namespace: tools
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: collabora
  template:
    metadata:
      labels:
        app: collabora
    spec:
      containers:
      - name: collabora
        image: collabora/code:25.04.9.1.1
        ports:
        - containerPort: 9980
        env:
        - name: aliasgroup1
          value: https://nextcloud.example.com
        securityContext:
          capabilities:
            add:
              - MKNOD
  1. Add the following content to nextcloud-db.yml:
---
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: nextcloud-db
  namespace: tools
spec:
  replicas: 2
  replication:
    enabled: true
    primary:
      podIndex: 0
  rootPasswordSecretKeyRef:
    name: nextcloud-secrets
    key: root-password
  username: nextcloud
  passwordSecretKeyRef:
    name: nextcloud-secrets
    key: user-password
  database: nextcloud
  port: 3306
  storage:
    size: 2Gi
    storageClassName: longhorn
  service:
    type: ClusterIP
  metrics:
    enabled: false
  tls:
    enabled: false
  1. Add the following content to nextcloud-ingress.yml:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nextcloud-ingress
  namespace: tools
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-cloudflare
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  ingressClassName: traefik
  tls:
  - hosts:
    - nextcloud.example.com
    secretName: nextcloud-tls
  rules:
  - host: nextcloud.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nextcloud-service
            port:
              number: 443

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: collabora-ingress
  namespace: tools
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-cloudflare
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  ingressClassName: traefik
  tls:
  - hosts:
    - collabora.example.com
    secretName: collabora-tls
  rules:
  - host: collabora.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: collabora-service
            port:
              number: 9980
  1. Add the following content to nextcloud-pvc.yml:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nextcloud-longhorn
  namespace: tools
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 2Gi
  storageClassName: longhorn

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nextcloud-data-longhorn
  namespace: tools
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 10Gi
  storageClassName: longhorn
  1. Add the following content to nextcloud-secret-tmp.yml:
---
apiVersion: v1
kind: Secret
metadata:
  name: nextcloud-secrets
  namespace: tools
type: Opaque
data:
  root-password: <base64-encoded-root-password>
  user-password: <base64-encoded-user-password>
  • Encrypt the secret using kubeseal.
    kubeseal -o yaml < nextcloud-secret-tmp.yml > nextcloud-secret.yml && \
    rm nextcloud-secret-tmp.yml
  1. Add the following content to nextcloud-svc.yml:
---
apiVersion: v1
kind: Service
metadata:
  name: nextcloud-service
  namespace: tools
  annotations:
    traefik.ingress.kubernetes.io/service.serversscheme: https
    traefik.ingress.kubernetes.io/service.serverstransport: tools-insecure-transport@kubernetescrd
spec:
  selector:
    app: nextcloud
  ports:
  - protocol: TCP
    port: 443
    targetPort: 443

---
apiVersion: v1
kind: Service
metadata:
  name: collabora-service
  namespace: tools
  annotations:
    traefik.ingress.kubernetes.io/service.serversscheme: https
    traefik.ingress.kubernetes.io/service.serverstransport: tools-insecure-transport@kubernetescrd
spec:
  selector:
    app: collabora
  ports:
  - protocol: TCP
    port: 9980
    targetPort: 9980
  • For this service to work, you need to create an insecureSkipVerify server transport in Traefik. You can do this by creating the following CRD:
    apiVersion: traefik.io/v1alpha1
    kind: ServersTransport
    metadata:
      name: insecure-transport
      namespace: tools
    spec:
      insecureSkipVerify: true
  1. Add the following content to nextcloud.yml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud
  namespace: tools
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nextcloud
  template:
    metadata:
      labels:
        app: nextcloud
    spec:
      containers:
      - name: nextcloud
        image: lscr.io/linuxserver/nextcloud:33.0.0
        ports:
        - containerPort: 443
        env:
        - name: PGID
          value: "1000"
        - name: PUID
          value: "1000"
        - name: TZ
          value: "Etc/UTC"
        volumeMounts:
        - name: nextcloud-data
          mountPath: /data
        - name: nextcloud-config
          mountPath: /config
      volumes:
      - name: nextcloud-data
        persistentVolumeClaim:
          claimName: nextcloud-data-longhorn
      - name: nextcloud-config
        persistentVolumeClaim:
          claimName: nextcloud-longhorn
  1. Commit and push the files to your Git repository. Flux will automatically deploy the resources to your cluster.