diff --git a/charts/nextcloud/Chart.yaml b/charts/nextcloud/Chart.yaml index ec72c02c..b8377e73 100644 --- a/charts/nextcloud/Chart.yaml +++ b/charts/nextcloud/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: nextcloud -version: 5.4.0 +version: 5.5.0-1 appVersion: 29.0.4 description: A file sharing server that puts the control and security of your own data back into your hands. keywords: diff --git a/charts/nextcloud/README.md b/charts/nextcloud/README.md index d6fad19a..73adf070 100644 --- a/charts/nextcloud/README.md +++ b/charts/nextcloud/README.md @@ -11,38 +11,38 @@ helm install my-release nextcloud/nextcloud ## Quick Links -* [Introduction](#introduction) -* [Prerequisites](#prerequisites) -* [Installing the Chart](#installing-the-chart) -* [Uninstalling the Chart](#uninstalling-the-chart) -* [Configuration](#configuration) - * [Database Configurations](#database-configurations) - * [Object Storage as Primary Storage Configuration](#object-storage-as-primary-storage-configuration) - * [Persistence Configurations](#persistence-configurations) - * [Metrics Configurations](#metrics-configurations) - * [Probes Configurations](#probes-configurations) -* [Cron jobs](#cron-jobs) -* [Using the nextcloud docker image auto-configuration via env vars](#using-the-nextcloud-docker-image-auto-configuration-via-env-vars) -* [Multiple config.php file](#multiple-configphp-file) -* [Using nginx](#using-nginx) - * [Service discovery with nginx and ingress](#service-discovery-with-nginx-and-ingress) -* [Preserving Source IP](#preserving-source-ip) -* [Hugepages](#hugepages) -* [HPA (Clustering)](#hpa-clustering) -* [Adjusting PHP ini values](#adjusting-php-ini-values) -* [Running `occ` commands](#running-occ-commands) - * [Putting Nextcloud into maintanence mode](#putting-nextcloud-into-maintanence-mode) - * [Downloading models for recognize](#downloading-models-for-recognize) -* [Backups](#backups) -* [Upgrades](#upgrades) -* [Troubleshooting](#troubleshooting) - * [Logging](#logging) - * [Changing the logging behavior](#changing-the-logging-behavior) - * [Viewing the logs](#viewing-the-logs) - * [Exec into the kubernetes pod:](#exec-into-the-kubernetes-pod) - * [Then look for the `nextcloud.log` file with tail or cat:](#then-look-for-the-nextcloudlog-file-with-tail-or-cat) - * [Copy the log file to your local machine:](#copy-the-log-file-to-your-local-machine) - * [Sharing the logs](#sharing-the-logs) +- [TL;DR;](#tldr) +- [Quick Links](#quick-links) +- [Introduction](#introduction) +- [Prerequisites](#prerequisites) +- [Installing the Chart](#installing-the-chart) +- [Uninstalling the Chart](#uninstalling-the-chart) +- [Configuration](#configuration) + - [Database Configurations](#database-configurations) + - [Object Storage as Primary Storage Configuration](#object-storage-as-primary-storage-configuration) + - [Persistence Configurations](#persistence-configurations) + - [Metrics Configurations](#metrics-configurations) + - [Probes Configurations](#probes-configurations) +- [Cron jobs](#cron-jobs) +- [Using the nextcloud docker image auto-configuration via env vars](#using-the-nextcloud-docker-image-auto-configuration-via-env-vars) +- [Multiple config.php file](#multiple-configphp-file) +- [Using nginx](#using-nginx) + - [Service discovery with nginx and ingress](#service-discovery-with-nginx-and-ingress) +- [Preserving Source IP](#preserving-source-ip) +- [Hugepages](#hugepages) +- [HPA (Clustering)](#hpa-clustering) +- [Adjusting PHP ini values](#adjusting-php-ini-values) +- [Running `occ` commands](#running-occ-commands) + - [Putting Nextcloud into maintanence mode](#putting-nextcloud-into-maintanence-mode) + - [Downloading models for recognize](#downloading-models-for-recognize) +- [Backup Cronjobs](#backup-cronjobs) +- [Logging](#logging) + - [Changing the logging behavior](#changing-the-logging-behavior) + - [Viewing the logs](#viewing-the-logs) + - [Exec into the kubernetes pod:](#exec-into-the-kubernetes-pod) + - [Then look for the `nextcloud.log` file with tail or cat:](#then-look-for-the-nextcloudlog-file-with-tail-or-cat) + - [Copy the log file to your local machine:](#copy-the-log-file-to-your-local-machine) + - [Sharing the logs](#sharing-the-logs) ## Introduction @@ -154,6 +154,7 @@ The following table lists the configurable parameters of the nextcloud chart and | `nextcloud.extraVolumeMounts` | specify additional volume mounts for the NextCloud pod | `{}` | | `nextcloud.securityContext` | Optional security context for the NextCloud container | `nil` | | `nextcloud.podSecurityContext` | Optional security context for the NextCloud pod (applies to all containers in the pod) | `nil` | +| `nextcloud.backupCronjobs` | specify data volume backup cronjobs ([see below](#backup-cronjobs)) | `[]` | | `nginx.enabled` | Enable nginx (requires you use php-fpm image) | `false` | | `nginx.image.repository` | nginx Image name, e.g. use `nginxinc/nginx-unprivileged` for rootless container | `nginx` | | `nginx.image.tag` | nginx Image tag | `alpine` | @@ -622,6 +623,74 @@ kubectl exec $NEXTCLOUD_POD -- su -s /bin/sh www-data -c "php occ recognize:down # Backups Check out the [official Nextcloud backup docs](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/backup.html). For your files, if you're using persistent volumes, and you'd like to back up to s3 backed storage (such as minio), consider using [k8up](https://github.com/k8up-io/k8up) or [velero](https://github.com/vmware-tanzu/velero). +## Backup Cronjobs + +Configure `.nextcloud.backupCronjobs` to install Kubernetes Cronjobs +to backup the Nextcloud data volume. The Helm chart automatically +shares the Nextcloud data folder to (`volumes`, `volumeMounts`) on the +same path. Additionally, it provides the environment variable +`NEXTCLOUD_DATA_DIR`. + +Example: + +```yaml + backupCronjobs: + - name: backup + schedule: "15 * * * *" + concurrencyPolicy: Forbid + startingDeadlineSeconds: 300 + successfulJobsHistoryLimit: 3 + suspend: false + jobTemplate: + spec: + backoffLimit: 1 + ttlSecondsAfterFinished: 300 + template: + spec: + restartPolicy: Never + containers: + - name: restic + image: restic/restic:0.16.4 + imagePullPolicy: IfNotPresent + command: + - /bin/sh + - -c + - "restic --quiet --json --host nextcloud-data --tag cron backup ${NEXTCLOUD_DATA_DIR}" + env: + - name: RESTIC_CACHE_DIR + value: /run/restic/cache + - name: RESTIC_CACERT + value: /run/secrets/ca-cert/ca.crt + - name: RESTIC_REPOSITORY + valueFrom: + secretKeyRef: + name: nextcloud-restic-repository + key: repository + - name: RESTIC_PASSWORD + valueFrom: + secretKeyRef: + name: nextcloud-restic-repository + key: password + volumeMounts: + - name: ca-cert + mountPath: /run/secrets/ca-cert + readOnly: true + - name: restic-cache + mountPath: /run/restic/cache + readOnly: false + terminationGracePeriodSeconds: 1 + volumes: + - name: ca-cert + secret: + secretName: restic-ca-cert + - name: restic-cache + emptyDir: {} +``` + +⚠️ *Please note that the Helm chart does not provide additional infrastructure (e.g., Kubernetes Secrets) to support backups.* + +See the [Kubernetes Cronjobs documentation](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) for more information. + # Upgrades Since this chart utilizes the [nextcloud/docker](https://github.com/nextcloud/docker) image, provided you are using persistent volumes, [upgrades of your Nextcloud server are handled automatically](https://github.com/nextcloud/docker#update-to-a-newer-version) from one version to the next, however, you can only upgrade one major version at a time. For example, if you want to upgrade from version `25` to `27`, you will have to upgrade from version `25` to `26`, then from `26` to `27`. Since our docker tag is set via the [`appVersion` in `Chart.yaml`](https://github.com/nextcloud/helm/blob/main/charts/nextcloud/Chart.yaml#L4), you'll need to make sure you gradually upgrade the helm chart if you have missed serveral app versions. diff --git a/charts/nextcloud/templates/_helpers.tpl b/charts/nextcloud/templates/_helpers.tpl index b0bf7355..703916a1 100644 --- a/charts/nextcloud/templates/_helpers.tpl +++ b/charts/nextcloud/templates/_helpers.tpl @@ -398,3 +398,24 @@ Create volume mounts for the nextcloud container as well as the cron sidecar con subPath: {{ $key }} {{- end }} {{- end -}} + +{{- define "nextcloud.backupCronJobEnv" -}} +- name: NEXTCLOUD_DATA_DIR + value: {{ .Values.nextcloud.datadir | quote }} +{{- end -}} + +{{- define "nextcloud.backupCronJobVolumes" -}} +{{- if and .Values.persistence.nextcloudData.enabled .Values.persistence.enabled }} +- name: nextcloud-data + persistentVolumeClaim: + claimName: {{ if .Values.persistence.nextcloudData.existingClaim }}{{ .Values.persistence.nextcloudData.existingClaim }}{{- else }}{{ template "nextcloud.fullname" . }}-nextcloud-data{{- end }} +{{- end }} +{{- end -}} + +{{- define "nextcloud.backupCronJobVolumeMounts" -}} +{{- if and .Values.persistence.nextcloudData.enabled .Values.persistence.enabled }} +- name: nextcloud-data + mountPath: {{ .Values.nextcloud.datadir }} + subPath: {{ ternary "data" (printf "%s/data" .Values.persistence.nextcloudData.subPath) (empty .Values.persistence.nextcloudData.subPath) }} +{{- end }} +{{- end -}} diff --git a/charts/nextcloud/templates/cronjobs.yaml b/charts/nextcloud/templates/cronjobs.yaml new file mode 100644 index 00000000..5d0b99c9 --- /dev/null +++ b/charts/nextcloud/templates/cronjobs.yaml @@ -0,0 +1,33 @@ +{{- range .Values.nextcloud.backupCronjobs }} +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ template "nextcloud.fullname" $ }}-backup-{{ .name }} +spec: + schedule: {{ .schedule }} + startingDeadlineSeconds: {{ .startingDeadlineSeconds }} + concurrencyPolicy: {{ .concurrencyPolicy }} + successfulJobsHistoryLimit: {{ .successfulJobsHistoryLimit }} + suspend: {{ .suspend }} + jobTemplate: + {{/* Add the volumes */}} + {{- $volumeList := concat (default list .jobTemplate.spec.template.spec.volumes) (include "nextcloud.backupCronJobVolumes" $ | fromYamlArray) -}} + {{- $volumes := dict "spec" (dict "template" (dict "spec" (dict "volumes" $volumeList))) -}} + {{- $jobTemplate := merge $volumes .jobTemplate -}} + + {{/* Add the volumeMounts and environment variables to every container */}} + {{- $containers := list -}} + {{- range .jobTemplate.spec.template.spec.containers -}} + {{- $vm := dict "volumeMounts" (concat (include "nextcloud.backupCronJobVolumeMounts" $ | fromYamlArray) (default list .volumeMounts)) -}} + {{- $c := merge $vm . -}} + {{- $env := dict "env" (concat (include "nextcloud.backupCronJobEnv" $ | fromYamlArray) (default list .env)) -}} + {{- $c = merge $env $c -}} + {{- $containers = append $containers $c -}} + {{- end -}} + + {{- $newContainers := dict "spec" (dict "template" (dict "spec" (dict "containers" $containers))) -}} + {{- $jobTemplate = merge $newContainers $jobTemplate -}} + + {{- $jobTemplate | toYaml | nindent 4 -}} +{{- end }} diff --git a/charts/nextcloud/values.yaml b/charts/nextcloud/values.yaml index 2d2d5d40..cb7f9a15 100644 --- a/charts/nextcloud/values.yaml +++ b/charts/nextcloud/values.yaml @@ -276,15 +276,71 @@ nextcloud: # - name: nextcloud-data # mountPath: /run/nextcloud/data + # Nextcloud data backup Cronjobs + # See https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/ + backupCronjobs: [] + # - name: backup + # schedule: "15 * * * *" + # concurrencyPolicy: Forbid + # startingDeadlineSeconds: 300 + # successfulJobsHistoryLimit: 3 + # suspend: false + # jobTemplate: + # spec: + # backoffLimit: 1 + # ttlSecondsAfterFinished: 300 + # template: + # spec: + # restartPolicy: Never + # containers: + # - name: restic + # image: restic/restic:0.16.4 + # imagePullPolicy: IfNotPresent + # command: + # - /bin/sh + # - -c + # - "restic --quiet --json --host nextcloud-data --tag cron backup ${NEXTCLOUD_DATA_DIR}" + # env: + # - name: TZ + # value: "Europe/Berlin" + # - name: RESTIC_CACHE_DIR + # value: /run/restic/cache + # - name: RESTIC_CACERT + # value: /run/secrets/ca-cert/ca.crt + # - name: RESTIC_REPOSITORY + # valueFrom: + # secretKeyRef: + # name: nextcloud-restic-repository + # key: repository + # - name: RESTIC_PASSWORD + # valueFrom: + # secretKeyRef: + # name: nextcloud-restic-repository + # key: password + # volumeMounts: + # - name: ca-cert + # mountPath: /run/secrets/ca-cert + # readOnly: true + # - name: restic-cache + # mountPath: /run/restic/cache + # readOnly: false + # terminationGracePeriodSeconds: 1 + # volumes: + # - name: ca-cert + # secret: + # secretName: restic-ca-cert + # - name: restic-cache + # emptyDir: {} + # Extra mounts for the pods. Example shown is for connecting a legacy NFS volume # to NextCloud pods in Kubernetes. This can then be configured in External Storage - extraVolumes: + extraVolumes: [] # - name: nfs # nfs: # server: "10.0.0.1" # path: "/nextcloud_data" # readOnly: false - extraVolumeMounts: + extraVolumeMounts: [] # - name: nfs # mountPath: "/legacy_data"