helm icon indicating copy to clipboard operation
helm copied to clipboard

Feature: maintanence mode cron jobs

Open jessebot opened this issue 2 years ago • 3 comments

Description of the change

Add optional nextcloud kubernetes cronjobs with configurable schedules for going into and out of maintenance modes. Ideally the cronjobs just run the following for "maintenance on":

# indexes the current files into the database before entering maintenance mode
# we index current files so the database backups include their metadata
su -s /bin/sh www-data -c "php occ files:scan --all && php occ maintenance:mode --on"

And then for the "maintenance off" job we'd would run:

# just takes nextcloud of maintenance mode
su -s /bin/sh www-data -c "php occ maintenance:mode --off"
example cronjob for maintenance mode on
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: nextcloud-maintanence-mode-on
  namespace: nextcloud
spec:
  # daily at 2:00AM Central Europe Time
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          volumes:
            - name: nextcloud-main
              persistentVolumeClaim:
                claimName: nextcloud-files
            - configMap:
                defaultMode: 420
                name: nextcloud-web-app-config
              name: nextcloud-config
            - configMap:
                defaultMode: 420
                name: nextcloud-web-app-nginxconfig
              name: nextcloud-nginx-config
          # consider this to chown /var/www/html/data and /data to www-data:root
          # initContainers:
          #   - name: nextcloud-maintanence-perm-fix
          containers:
            - name: nextcloud-maintanence
              image: nextcloud:27.0.0-fpm
              imagePullPolicy: IfNotPresent
              command:
                - /bin/bash
                - -c
                - su -s /bin/bash www-data -c "php occ files:scan --all && php occ maintenance:mode --on"
              volumeMounts:
                - mountPath: /var/www/
                  name: nextcloud-main
                  subPath: root
                - mountPath: /var/www/html
                  name: nextcloud-main
                  subPath: html
                # only needed if you have a seperate data dir for nextcloud
                - mountPath: /var/www/html/data
                  name: nextcloud-main
                  subPath: data
                - mountPath: /var/www/html/config
                  name: nextcloud-main
                  subPath: config
                - mountPath: /var/www/html/custom_apps
                  name: nextcloud-main
                  subPath: custom_apps
                - mountPath: /var/www/tmp
                  name: nextcloud-main
                  subPath: tmp
                - mountPath: /var/www/html/themes
                  name: nextcloud-main
                  subPath: themes
                - mountPath: /var/www/html/config/logging.config.php
                  name: nextcloud-config
                  subPath: logging.config.php
                - mountPath: /var/www/html/config/proxy.config.php
                  name: nextcloud-config
                  subPath: proxy.config.php
                - mountPath: /var/www/html/config/.htaccess
                  name: nextcloud-config
                  subPath: .htaccess
                - mountPath: /var/www/html/config/apache-pretty-urls.config.php
                  name: nextcloud-config
                  subPath: apache-pretty-urls.config.php
                - mountPath: /var/www/html/config/apcu.config.php
                  name: nextcloud-config
                  subPath: apcu.config.php
                - mountPath: /var/www/html/config/apps.config.php
                  name: nextcloud-config
                  subPath: apps.config.php
                - mountPath: /var/www/html/config/autoconfig.php
                  name: nextcloud-config
                  subPath: autoconfig.php
                - mountPath: /var/www/html/config/smtp.config.php
                  name: nextcloud-config
                  subPath: smtp.config.php
              env:
                - name: POSTGRES_HOST
                  value: nextcloud-web-app-postgresql
                - name: POSTGRES_DB
                  value: nextcloud
                - name: POSTGRES_USER
                  valueFrom:
                    secretKeyRef:
                      key: username
                      name: nextcloud-pgsql-credentials
                - name: POSTGRES_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      key: nextcloudPassword
                      name: nextcloud-pgsql-credentials
                - name: NEXTCLOUD_ADMIN_USER
                  valueFrom:
                    secretKeyRef:
                      key: username
                      name: nextcloud-admin-credentials
                - name: NEXTCLOUD_ADMIN_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      key: password
                      name: nextcloud-admin-credentials
                # - name: NEXTCLOUD_TRUSTED_DOMAINS
                #   value: cloud.example.com
                - name: NEXTCLOUD_DATA_DIR
                  value: /var/www/html/data

Benefits

Right now, to create backups, you need to put nextcloud into maintenance mode and that would need to be done manually with an occ command. I'm using k8up to backup nextcloud, but it requires me to maintain two Kubernetes Cronjobs to put nextcloud into maintenance mode before the backup and then take it out of maintenance mode after the backup is done. The issue is that these cronjobs have to replicate the nextcloud pod, which means also keeping the same nextcloud image version, to avoid any issues with accidentally upgrading or downgrading anything.

If this is implemented, it would allow users to set a specific window that their backups could run through the use of something like k8up or velero or even just their own homegrown rsync or restic kubernetes cronjob.

Possible drawbacks

It's kind of confusing to have both our sidecar crobjob, for automated nextcloud maintanence tasks and this potentially additional kubernetes cronjob, however the Kubernetes side car job only handles background tasks, which can include backups, but the baked in nextcloud server backups are not done with restic, I don't think, and there's been complaints of the storage space it takes. I think this makes sense to implement anyway because it's one less manual k8s resource you need to maintain alongside the helm chart.

Additional information

I can submit a PR for this, but we'd have two cronjobs to template, and then the main values we'd be adding to values.yaml would be:

maintenance_mode_cronjobs:
  # set to true to enable maintenance mode via a kubernetes cronjob during a specific window
  enabled: false
  # time to run the maintenance mode on job
  # example to start maintenance mode daily at 2:00AM UTC
  # start_schedule: "0 2 * * *"
  start_schedule: ""
  # time to run the maintenance mode off job
  # example to stop maintenance mode daily at 3:00AM UTC
  # end_schedule: "0 3 * * *"
  end_schedule: ""

I'm personally going to be using s3 compliant object storage as my primary storage, but I still need maintenance mode for backing up the database.

jessebot avatar Sep 01 '23 09:09 jessebot

ok, I re-read the nextcloud backup app's README and it looks like they do support differential backups, so I will test that, and if it works, I will report back and close this issue.

Update: Could not get the backups app to work, but it seems a lot of users have had issues with getting it to work in a container :shrug:

jessebot avatar Sep 02 '23 10:09 jessebot

Have you considered pre and post hooks with your backup system? I've used velero's hooks successfully in the past for similar things.

pschichtel avatar May 31 '24 11:05 pschichtel

velero was a bit too slow for me, so I switched to k8up. They have a concept of a pre-backup pod, but not a post-backup pod though.

My cronjobs are still hardcoded to be a specific nextcloud docker image tag, which is not great, because I have to remember to update them all the time, but unfortunately, that's just kind of the case until we would introduce a proper maintainence mode cronjob here. You can see my full setup here: https://github.com/small-hack/argocd-apps/tree/main/nextcloud

The cronjobs are here specifically: https://github.com/small-hack/argocd-apps/tree/main/nextcloud/maintenance_mode_cronjobs/templates

jessebot avatar May 31 '24 12:05 jessebot