Nextcloud Helm Chart

Nextcloud is a file sharing server that puts the control and security of your own data back into your hands.

TL;DR;

helm repo add nextcloud https://nextcloud.github.io/helm/
helm install my-release nextcloud/nextcloud

Introduction

This chart bootstraps an nextcloud deployment on a Kubernetes cluster using the Helm package manager.

You will also need a database compatible with Nextcloud. For more info, please see the Database Configuration section below.

If you want to persist data accross installs and upgrades, you’ll need to configure persistence. For more info, please see the Persistence Configuration section below.

We also package the following helm charts from Bitnami for you to optionally use:

ChartDescrption
RedisFor enabling caching
PostgreSQLFor use as an external database
MariaDBFor use as an external database

Prerequisites

Installing the Chart

To install the chart with the release name my-release:

helm repo add nextcloud https://nextcloud.github.io/helm/
helm install my-release nextcloud/nextcloud

The command deploys nextcloud on the Kubernetes cluster in the default configuration. The configuration section lists the parameters that can be configured during installation.

Tip: List all releases using helm list

Uninstalling the Chart

To uninstall/delete the my-release deployment:

helm delete my-release

The command removes all the Kubernetes components associated with the chart and deletes the release.

Upgrade / Breaking Changes

There is a Changelog of breaking changes here: CHANGELOG.md. You should read it bevore updating.

Configuration

The following table lists the configurable parameters of the nextcloud chart and their default values.

ParameterDescriptionDefault
image.repositorynextcloud Image namenextcloud
image.flavornextcloud Image type (Options: apache, fpm)apache
image.tagnextcloud Image tagappVersion
image.pullPolicyImage pull policyIfNotPresent
image.pullSecretsSpecify image pull secretsnil
replicaCountNumber of nextcloud pods to deploy1
ingress.classNameName of the ingress class to usenil
ingress.enabledEnable use of ingress controllersfalse
ingress.servicePortIngress’ backend servicePorthttp
ingress.annotationsAn array of service annotationsnil
ingress.labelsAn array of service labelsnil
ingress.pathThe Path to use in Ingress’ paths/
ingress.pathTypeThe PathType to use in Ingress’ pathsPrefix
ingress.tlsIngress TLS configuration[]
nextcloud.hostnextcloud host to create application URLs, updates trusted_domains at installation time onlynextcloud.kube.home
nextcloud.usernameUser of the applicationadmin
nextcloud.passwordApplication passwordchangeme
nextcloud.existingSecret.enabledWhether to use an existing secret or notfalse
nextcloud.existingSecret.secretNameName of the existing secretnil
nextcloud.existingSecret.usernameKeyName of the key that contains the usernamenil
nextcloud.existingSecret.passwordKeyName of the key that contains the passwordnil
nextcloud.existingSecret.smtpUsernameKeyName of the key that contains the SMTP usernamenil
nextcloud.existingSecret.smtpPasswordKeyName of the key that contains the SMTP passwordnil
nextcloud.existingSecret.smtpHostKeyName of the key that contains the SMTP hostnamenil
nextcloud.existingSecret.tokenKeyName of the key that contains the nextcloud metrics token''
nextcloud.updateTrigger update if custom command is used0
nextcloud.containerPortCustomize container port when not running as root80
nextcloud.trustedDomainsOptional space-separated list of trusted domains[]
nextcloud.datadirnextcloud data dir location/var/www/html/data
nextcloud.mail.enabledWhether to enable/disable email settingsfalse
nextcloud.mail.fromAddressnextcloud mail send from fieldnil
nextcloud.mail.domainnextcloud mail domainnil
nextcloud.mail.smtp.hostSMTP hostnamenil
nextcloud.mail.smtp.secureSMTP connection ssl or empty''
nextcloud.mail.smtp.portOptional SMTP portnil
nextcloud.mail.smtp.authtypeSMTP authentication methodLOGIN
nextcloud.mail.smtp.nameSMTP username, ONLY the part before the domain name. i.e. ‘postmaster’ NOT ‘postmaster@example.com’''
nextcloud.mail.smtp.passwordSMTP password''
nextcloud.configsConfig files created in /var/www/html/config{}
nextcloud.persistence.subPathSet the subPath for nextcloud to use in volumenil
nextcloud.phpConfigsPHP Config files created in /usr/local/etc/php/conf.d{}
nextcloud.defaultConfigs.\.htaccessDefault .htaccess to protect /var/www/html/configtrue
nextcloud.defaultConfigs.apache-pretty-urls\.config\.phpDefault Apache configuration for rewrite urlstrue
nextcloud.defaultConfigs.apcu\.config\.phpDefault configuration to define APCu as local cachetrue
nextcloud.defaultConfigs.apps\.config\.phpDefault configuration for appstrue
nextcloud.defaultConfigs.autoconfig\.phpDefault auto-configuration for databasestrue
nextcloud.defaultConfigs.redis\.config\.phpDefault Redis configurationtrue
nextcloud.defaultConfigs.reverse-proxy\.config\.phpDefault Reverse proxy configurationtrue
nextcloud.defaultConfigs.s3\.config\.phpDefault configuration for S3 as primary Object Storagetrue
nextcloud.defaultConfigs.smtp\.config\.phpDefault configuration for smtptrue
nextcloud.defaultConfigs.swift\.config\.phpDefault configuration for Swift as primary Object Storagetrue
nextcloud.defaultConfigs.upgrade-disable-web\.config\.phpDefault config to disable the web-based updater as the default docker image does not suppor ittrue
nextcloud.strategyspecifies the strategy used to replace old Pods by new onestype: Recreate
nextcloud.extraEnvspecify additional environment variables{}
nextcloud.extraSidecarContainersspecify additional sidecar containers[]
nextcloud.extraInitContainersspecify additional init containers[]
nextcloud.extraVolumesspecify additional volumes for the NextCloud pod{}
nextcloud.extraVolumeMountsspecify additional volume mounts for the NextCloud pod{}
nextcloud.mariaDbInitContainer.resourcesset the resources field of the MariaDB init container in the Nextcloud Pod.{}
nextcloud.mariaDbInitContainer.securityContextset the securityContext field of the MariaDB init container in the Nextcloud Pod.{}
nextcloud.postgreSqlInitContainer.resourcesset the resources field of the PostgreSQL init container in the Nextcloud Pod.{}
nextcloud.postgreSqlInitContainer.securityContextset the securityContext field of the PostgreSQL init container in the Nextcloud Pod.{}
nextcloud.securityContextOptional security context for the NextCloud containernil
nextcloud.podSecurityContextOptional security context for the NextCloud pod (applies to all containers in the pod)nil
nextcloud.postgreSqlInitContainer.securityContextSet postgresql initContainer securityContext parameters.{}
nginx.enabledEnable nginx (requires you use php-fpm image)false
nginx.image.repositorynginx Image name, e.g. use nginxinc/nginx-unprivileged for rootless containernginx
nginx.image.tagnginx Image tagalpine
nginx.image.pullPolicynginx Image pull policyIfNotPresent
nginx.image.pullPolicynginx Image pull policyIfNotPresent
nginx.containerPortCustomize container port e.g. when not running as rootIfNotPresent
nginx.ipFamiliesCustomize container to listen on IPv4, IPv6 or both["IPv4"]
nginx.config.defaultWhether to use nextcloud’s recommended nginx configtrue
nginx.config.customSpecify a custom config for nginx{}
nginx.resourcesnginx resources{}
nginx.securityContextOptional security context for the nginx containernil
nginx.extraEnvOptional environment variables for the nginx containernil
lifecycle.postStartCommandSpecify deployment lifecycle hook postStartCommandnil
lifecycle.preStopCommandSpecify deployment lifecycle hook preStopCommandnil
redis.enabledWhether to install/use redis for lockingfalse
redis.auth.enabledWhether to enable password authentication with redistrue
redis.auth.passwordThe password redis uses''
redis.auth.existingSecretThe name of an existing secret with Redis® credentials''
redis.auth.existingSecretPasswordKeyPassword key to be retrieved from existing secret''
redis.global.storageClassPVC Storage Class for both Redis® master and replica Persistent Volumes''
redis.master.persistence.enabledEnable persistence on Redis® master nodes using Persistent Volume Claimstrue
redis.replica.persistence.enabledEnable persistence on Redis® replica nodes using Persistent Volume Claimstrue
externalRedis.enabledWhether to use external Redisfalse
externalRedis.hostRedis host""
externalRedis.portRedis port"6379"
externalRedis.passwordRedis password""
externalRedis.existingSecret.enabledWhether to use a existing secret or notfalse
externalDatabase.existingSecret.secretNameName of the existing secretnil
externalDatabase.existingSecret.passwordKeyName of the key that contains the Redis passwordredis-password
cronjob.enabledWhether to enable/disable cron jobsfalse
cronjob.typeChoose which cron implementation to use. Either sidecar or cronjob.sidecar
cronjob.sidecar.commandThe command the cronjob sidecar container executes/cron.sh
cronjob.sidecar.lifecycle.postStartCommandSpecify deployment lifecycle hook postStartCommand for the cron jobs sidecarnil
cronjob.sidecar.lifecycle.preStopCommandSpecify deployment lifecycle hook preStopCommand for the cron jobs sidecarnil
cronjob.sidecar.resourcesCPU/Memory resource requests/limits for the cron jobs sidecar{}
cronjob.sidecar.securityContextOptional security context for cron jobs sidecarnil
cronjob.cronjob.scheduleCron job schedule*/5 * * * *
cronjob.cronjob.successfulJobsHistoryLimitNumber of successful jobs to keep in history3
cronjob.cronjob.failedJobsHistoryLimitNumber of failed jobs to keep in history5
cronjob.cronjob.labelsAn array of service labelsnil
cronjob.cronjob.podLabelsAn array of service labelsnil
cronjob.cronjob.annotationsAn array of service annotationsnil
cronjob.cronjob.backoffLimitThe number of retries before marking a job as failed1
cronjob.cronjob.affinityThe affinity settings for the cron job{}
cronjob.cronjob.resourcesThe resource requests/limits for the cron job{}
cronjob.cronjob.securityContextOptional security context for cronjobsnil
cronjob.cronjob.commandThe command the cronjob executes["php", "-f", "/var/www/html/cron.php", "--", "--verbose"]
service.typeKubernetes Service typeClusterIP
service.loadBalancerIPLoadBalancerIp for service type LoadBalancer""
service.annotationsAnnotations for service type{}
service.nodePortNodePort for service type NodePortnil
service.ipFamiliesSet ipFamilies as in k8s service objectsnil
service.ipFamyPolicydefine IP protocol bindings as in k8s service objectsnil
service.sessionAffinityKubernetes service Session Affinitynil
service.sessionAffinityConfigKubernetes service Session Affinity configuration{}
phpClientHttpsFix.enabledSets OVERWRITEPROTOCOL for https ingress redirectfalse
phpClientHttpsFix.protocolSets OVERWRITEPROTOCOL for https ingress redirecthttps
resourcesCPU/Memory resource requests/limits{}
rbac.enabledEnable Role and rolebinding for priveledged PSPfalse
rbac.serviceaccount.createWether to create a serviceaccount or use an existing one (requires rbac)true
rbac.serviceaccount.nameThe name of the sevice account that the deployment will use (requires rbac)nextcloud-serviceaccount
rbac.serviceaccount.annotationsServiceaccount annotations{}
hpa.enabledBoolean to create a HorizontalPodAutoscaler. If set to true, ignores replicaCount.false
hpa.cputhresholdCPU threshold percent for the HorizontalPodAutoscale60
hpa.minPodsMin. pods for the Nextcloud HorizontalPodAutoscaler1
hpa.maxPodsMax. pods for the Nextcloud HorizontalPodAutoscaler10
deploymentLabelsLabels to be added at ‘deployment’ levelnot set
deploymentAnnotationsAnnotations to be added at ‘deployment’ levelnot set
podLabelsLabels to be added at ‘pod’ levelnot set
podAnnotationsAnnotations to be added at ‘pod’ levelnot set
dnsConfigCustom dnsConfig for nextcloud containers{}

Ingress

Ingress Sticky-Sessions

For loadbalance over multiple Pods, it is useful to configure sticky session.

NGINX Ingress-Controller

To enable sticky sessions on that ingress controller you could set the following values in this helm-chart. For more information take a look in the ingress-controller documentation

ingress:
  annotations:
    nginx.ingress.kubernetes.io/affinity: cookie
Traefik Ingress-Controller

To enable sticky sessions on that ingress controller you could set the following values in this helm-chart. For more information take a look in the ingress-controller documentation

service:
  annotations:
    traefik.ingress.kubernetes.io/service.sticky.cookie: "true"
HAProxy Ingress-Controller (Community-Version)

To enable sticky sessions on that ingress controller you could set the following values in this helm-chart. For more infromation take a look in the ingress-controller documentation

ingress:
  annotations:
    haproxy-ingress.github.io/affinity: cookie

Database Configurations

By default, nextcloud will use a SQLite database. This is not recommended for production, but is enabled by default for testing purposes. When you are done testing, please set internalDatabase.enabled to false, and configure the externalDatabase parameters below.

For convenience, we packages the following Bitnami charts for databases (feel free to choose one below):

If you choose to use one of the prepackaged Bitnami helm charts, you must configure both the externalDatabase parameters, and the parameters for the chart you choose. For instance, if you choose to use the Bitnami PostgreSQL chart that we’ve prepackaged, you need to also configure all the parameters for postgresql. You do not need to use the Bitnami helm charts. If you want to use an already configured database that you have externally, just set internalDatabase.enabled to false, and configure the externalDatabase parameters below.

ParameterDescriptionDefault
internalDatabase.enabledWhether to use internal sqlite databasetrue
internalDatabase.databaseName of the existing databasenextcloud
externalDatabase.enabledWhether to use external databasefalse
externalDatabase.typeExternal database type: mysql, postgresqlmysql
externalDatabase.hostHost of the external database in form of host:port. Example: "myhost:1234"""
externalDatabase.databaseName of the existing databasenextcloud
externalDatabase.userExisting username in the external dbnextcloud
externalDatabase.passwordPassword for the above usernamenil
externalDatabase.existingSecret.enabledWhether to use a existing secret or notfalse
externalDatabase.existingSecret.secretNameName of the existing secretnil
externalDatabase.existingSecret.usernameKeyName of the key that contains the usernamenil
externalDatabase.existingSecret.passwordKeyName of the key that contains the passwordnil
externalDatabase.existingSecret.hostKeyName of the key that contains the database hostname or IP addressnil
externalDatabase.existingSecret.databaseKeyName of the key that contains the database namenil
mariadb.enabledWhether to use the MariaDB chartfalse
mariadb.auth.databaseDatabase name to createnextcloud
mariadb.auth.usernameDatabase user to createnextcloud
mariadb.auth.passwordPassword for the databasechangeme
mariadb.auth.rootPasswordMariaDB admin passwordnil
mariadb.auth.existingSecretUse existing secret for MariaDB password details; see values.yaml for more detail''
mariadb.image.registryMariaDB image registrydocker.io
mariadb.image.repositoryMariaDB image repositorybitnami/mariadb
mariadb.image.tagMariaDB image tag``
mariadb.global.defaultStorageClassMariaDB Global default StorageClass for Persistent Volume(s)''
mariadb.primary.persistence.enabledWhether or not to Use a PVC on MariaDB primaryfalse
mariadb.primary.persistence.storageClassMariaDB primary persistent volume storage Class''
mariadb.primary.persistence.existingClaimUse an existing PVC for MariaDB primary''
postgresql.enabledWhether to use the PostgreSQL chartfalse
postgresql.image.registryPostgreSQL image registrydocker.io
postgresql.image.repositoryPostgreSQL image repositorybitnami/postgresql
postgresql.image.tagPostgreSQL image tag15.4.0-debian-11-r10
postgresql.global.postgresql.auth.databaseDatabase name to createnextcloud
postgresql.global.postgresql.auth.usernameDatabase user to createnextcloud
postgresql.global.postgresql.auth.passwordPassword for the databasechangeme
postgresql.global.postgresql.auth.existingSecretName of existing secret to use for PostgreSQL credentials''
postgresql.global.postgresql.auth.secretKeys.adminPasswordKeyName of key in existing secret to use for PostgreSQL admin password''
postgresql.global.postgresql.auth.secretKeys.userPasswordKeyName of key in existing secret to use for PostgreSQL user password''
postgresql.global.postgresql.auth.secretKeys.replicationPasswordKeyName of key in existing secret to use for PostgreSQL replication password''
postgresql.primary.persistence.enabledWhether or not to use PVC on PostgreSQL primaryfalse
postgresql.primary.persistence.existingClaimUse an existing PVC for PostgreSQL primarynil

Is there a missing parameter for one of the Bitnami helm charts listed above? Please feel free to submit a PR to add that parameter in our values.yaml, but be sure to also update this README file :)

Object Storage as Primary Storage Configuration

Nextcloud allows to configure object storages like OpenStack Swift or Amazon Simple Storage Service (S3) or any compatible S3-implementation (e.g. Minio or Ceph Object Gateway) as primary storage replacing the default storage of files.

By default, files are stored in nextcloud/data or another directory configured in the config.php of your Nextcloud instance. This data directory might still be used for compatibility reasons)

Read more in the official docs.

Here are all the values you can currently configure in this helm chart to configure an Object Store as your Primary Storage.

ParameterDescriptionDefault
nextcloud.objectStore.s3.enabledenable configuring S3 as a primary object storefalse
nextcloud.objectStore.s3.accessKeyaccessKeyID for authing to S3, ignored if using existingSecret''
nextcloud.objectStore.s3.secretKeysecretAccessKey for authing to S3, ignored if using existingSecret''
nextcloud.objectStore.s3.legacyAuthuse legacy authentication for S3false
nextcloud.objectStore.s3.hostendpoint URL to connect to. Only required if not using AWS''
nextcloud.objectStore.s3.sslUse TLS connection when connecting to S3true
nextcloud.objectStore.s3.portPort for S3 host to use443
nextcloud.objectStore.s3.regionregion to look for bucket in on the S3 hosteu-west-1
nextcloud.objectStore.s3.bucketbucket on the S3 host''
nextcloud.objectStore.s3.prefixoptional object prefix''
nextcloud.objectStore.s3.usePathStyleset to true if you are not using DNS for your bucketsfalse
nextcloud.objectStore.s3.autoCreateauto-create the S3 bucketfalse
nextcloud.objectStore.s3.storageClassS3 storage class to useSTANDARD
nextcloud.objectStore.s3.sse_c_keyS3 server side encryption key.''
nextcloud.objectStore.s3.existingSecretUse an existing Kubernetes Secret to fetch auth credentials''
nextcloud.objectStore.s3.secretKeys.hostif using s3.existingSecret, secret key to use for the host''
nextcloud.objectStore.s3.secretKeys.accessKeyif using s3.existingSecret, secret key to use for the accessKeyID''
nextcloud.objectStore.s3.secretKeys.secretKeyif using s3.existingSecret, secret key to use for the secretAccessKey''
nextcloud.objectStore.s3.secretKeys.bucketif using s3.existingSecret, secret key to use for the bucket''
nextcloud.objectStore.s3.secretKeys.sse_c_keyif using s3.existingSecret, secret key to use for the sse_c_key''
nextcloud.objectStore.swift.enabledenable configuring Openstack Swift as a primary object storefalse
nextcloud.objectStore.swift.user.domainoptional: swift user domain'Default'
nextcloud.objectStore.swift.user.nameSwift username''
nextcloud.objectStore.swift.user.passwordSwift user password''
nextcloud.objectStore.swift.project.nameSwift project name''
nextcloud.objectStore.swift.project.domainoptional: swift project domain'Default'
nextcloud.objectStore.swift.urlSwift Identity / Keystone endpoint''
nextcloud.objectStore.swift.regionSwift region''
nextcloud.objectStore.swift.serviceOptional: service name, used on some swift implementations'swift'
nextcloud.objectStore.swift.containerSwift container to store the data in''
nextcloud.objectStore.swift.autoCreateAutocreate the Swift containerfalse

Persistence Configurations

The Nextcloud image stores the nextcloud data and configurations at the /var/www/html paths of the container. Persistent Volume Claims are used to keep the data across deployments. This is known to work with GKE, EKS, K3s, and minikube. Nextcloud will not delete the PVCs when uninstalling the helm chart.

ParameterDescriptionDefault
persistence.enabledEnable persistence using PVCfalse
persistence.annotationsPVC annotations{}
persistence.storageClassPVC Storage Class for nextcloud volumenil
persistence.existingClaimAn Existing PVC name for nextcloud volumenil
persistence.accessModePVC Access Mode for nextcloud volumeReadWriteOnce
persistence.sizePVC Storage Request for nextcloud volume8Gi
persistence.nextcloudData.enabledCreate a second PVC for the data folder in nextcloudfalse
persistence.nextcloudData.annotationssee persistence.annotations{}
persistence.nextcloudData.storageClasssee persistence.storageClassnil
persistence.nextcloudData.existingClaimsee persistence.existingClaimnil
persistence.nextcloudData.accessModesee persistence.accessModeReadWriteOnce
persistence.nextcloudData.sizesee persistence.size8Gi

Metrics Configurations

We include an optional experimental Nextcloud Metrics exporter from xperimental/nextcloud-exporter.

ParameterDescriptionDefault
metrics.enabledStart Prometheus metrics exporterfalse
metrics.replicaCountNumber of nextcloud-metrics pod replicas to deploy1
metrics.serverNextcloud Server URL to get metrics from. If not provided, defaults to service name""
metrics.httpsDefines if https is used to connect to nextcloudfalse (uses http)
metrics.tokenUses token for auth instead of username/password""
metrics.timeoutWhen the scrape times out5s
metrics.tlsSkipVerifySkips certificate verification of Nextcloud serverfalse
metrics.info.appsEnable gathering of apps-related metrics.false
metrics.image.repositoryNextcloud metrics exporter image namexperimental/nextcloud-exporter
metrics.image.tagNextcloud metrics exporter image tag0.6.2
metrics.image.pullPolicyNextcloud metrics exporter image pull policyIfNotPresent
metrics.image.pullSecretsNextcloud metrics exporter image pull secretsnil
metrics.podAnnotationsAdditional annotations for metrics exporternot set
metrics.podLabelsAdditional labels for metrics exporternot set
metrics.service.typeMetrics: Kubernetes Service typeClusterIP
metrics.service.loadBalancerIPMetrics: LoadBalancerIp for service type LoadBalancernil
metrics.service.nodePortMetrics: NodePort for service type NodePortnil
metrics.service.annotationsAdditional annotations for service metrics exporter{prometheus.io/scrape: "true", prometheus.io/port: "9205"}
metrics.service.labelsAdditional labels for service metrics exporter{}
metrics.serviceMonitor.enabledCreate ServiceMonitor Resource for scraping metrics using PrometheusOperatorfalse
metrics.serviceMonitor.namespaceNamespace in which Prometheus is running``
metrics.serviceMonitor.jobLabelName of the label on the target service to use as the job name in prometheus``
metrics.serviceMonitor.intervalInterval at which metrics should be scraped30s
metrics.serviceMonitor.scrapeTimeoutSpecify the timeout after which the scrape is ended``
metrics.serviceMonitor.labelsExtra labels for the ServiceMonitor`{}

Note:

For nextcloud to function correctly, you should specify the nextcloud.host parameter to specify the FQDN (recommended) or the public IP address of the nextcloud service.

Optionally, you can specify the service.loadBalancerIP parameter to assign a reserved IP address to the nextcloud service of the chart. However please note that this feature is only available on a few cloud providers (f.e. GKE).

To reserve a public IP address on GKE:

gcloud compute addresses create nextcloud-public-ip

The reserved IP address can be associated to the nextcloud service by specifying it as the value of the service.loadBalancerIP parameter while installing the chart.

Specify each parameter using the --set key=value[,key=value] argument to helm install. For example,

helm install --name my-release \
  --set nextcloud.username=admin,nextcloud.password=password,mariadb.auth.rootPassword=secretpassword \
    nextcloud/nextcloud

The above command sets the nextcloud administrator account username and password to admin and password respectively. Additionally, it sets the MariaDB root user password to secretpassword.

Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,

helm install --name my-release -f values.yaml nextcloud/nextcloud

Tip: You can use the default values.yaml

Headers set on NGINX

It is possible to set any additional header

ParameterDescriptionDefault
nginx.config.headers.<key>Headers which are added with nginx

Following keys are already set with this values:

Maybe you like to set:

[!WARNING] Only add the preload option once you read about the consequences in https://hstspreload.org/. This option will add the domain to a hardcoded list that is shipped in all major browsers and getting removed from this list could take several months.

Probes Configurations

The nextcloud deployment includes a series of different probes you can use to determine if a pod is ready or not. You can learn more in the Configure Liveness, Readiness and Startup Probes Kubernetes docs.

ParameterDescriptionDefault
livenessProbe.enabledTurn on and off liveness probetrue
livenessProbe.initialDelaySecondsDelay before liveness probe is initiated10
livenessProbe.periodSecondsHow often to perform the probe10
livenessProbe.timeoutSecondsWhen the probe times out5
livenessProbe.failureThresholdMinimum consecutive failures for the probe3
livenessProbe.successThresholdMinimum consecutive successes for the probe1
readinessProbe.enabledTurn on and off readiness probetrue
readinessProbe.initialDelaySecondsDelay before readiness probe is initiated10
readinessProbe.periodSecondsHow often to perform the probe10
readinessProbe.timeoutSecondsWhen the probe times out5
readinessProbe.failureThresholdMinimum consecutive failures for the probe3
readinessProbe.successThresholdMinimum consecutive successes for the probe1
startupProbe.enabledTurn on and off startup probefalse
startupProbe.initialDelaySecondsDelay before readiness probe is initiated30
startupProbe.periodSecondsHow often to perform the probe10
startupProbe.timeoutSecondsWhen the probe times out5
startupProbe.failureThresholdMinimum consecutive failures for the probe30
startupProbe.successThresholdMinimum consecutive successes for the probe1

[!Note] If you are getting errors on initialization (such as Fatal error: require_once(): Failed opening required '/var/www/html/lib/versioncheck.php', but you can get other errors as well), a good first step is to try and enable the startupProbe and/or increase the initialDelaySeconds for the livenessProbe and readinessProbe to something much greater (consider using 120 seconds instead of 10. This is an especially good idea if your cluster is running on older hardware, has a slow internet connection, or you’re using a slower storage class, such as NFS that’s running with older disks or a slow connection.

Collabora Configuration

This section provides options to enable and configure the Collabora Online server within your deployment. Please ensure to review the Collabora Online Helm chart documentation for additional details and recommended values.

ParameterDescriptionDefault
collabora.enabledEnable or disable the Collabora Online integrationfalse
collabora.autoscaling.enabledEnable or disable autoscaling for the Collabora Online podsfalse
collabora.collabora.aliasgroupsList of HTTPS nextcloud domains if Collabora is behind a reverse proxy[]
collabora.collabora.extra_paramsAdditional parameters for the Collabora Online service"--o:ssl.enabled=false"
collabora.collabora.server_nameSpecify the server name when the hostname is not directly reachable (e.g., behind a reverse proxy)null
collabora.collabora.existingSecret.enabledEnable using existing secret for admin login credentialsfalse
collabora.collabora.existingSecret.secretNameName of the existing secret containing admin login credentials""
collabora.collabora.existingSecret.usernameKeyKey in the secret for the admin username"username"
collabora.collabora.existingSecret.passwordKeyKey in the secret for the admin password"password"
collabora.collabora.usernameAdmin username for Collabora Onlineadmin
collabora.collabora.passwordAdmin password for Collabora Onlineexamplepass
collabora.ingress.enabledEnable or disable ingress for Collabora Onlinefalse
collabora.ingress.classNameClass name for the ingress controller""
collabora.ingress.annotationsAnnotations for the ingress resource{}
collabora.ingress.hostsList of hosts for the Collabora ingress[{"host": "chart-example.local", "paths": [{"path": "/", "pathType": "ImplementationSpecific"}]}]
collabora.ingress.tlsTLS configuration for the Collabora ingress[]
collabora.resourcesResource requests and limits for the Collabora Online pods{}

Note:

You may need to uncomment collabora.collabora.aliasgroups and collabora.collabora.extra_params, depending on your setup. You may also need to set collabora.collabora.server_name. If left empty, it’s derived from the request, so please set it if it doesn’t work.

If you have both Nextcloud and Collabora behind a reverse proxy with HTTPS, collabora.collabora.aliasgroups should match your Nextcloud domain and collabora.collabora.server_name (if needed) should match your Collabora domain.

For more information, please check the Collabora documentation.

Imaginary

We include an optional external preview provider from h2non/imaginary.

ParameterDescriptionDefault
imaginary.enabledStart Imaginaryfalse
imaginary.replicaCountNumber of imaginary pod replicas to deploy1
imaginary.image.registryImaginary image namedocker.io
imaginary.image.repositoryImaginary image nameh2non/imaginary
imaginary.image.tagImaginary image tag1.2.4
imaginary.image.pullPolicyImaginary image pull policyIfNotPresent
imaginary.image.pullSecretsImaginary image pull secretsnil
imaginary.podAnnotationsAdditional annotations for imaginary{}
imaginary.podLabelsAdditional labels for imaginary{}
imaginary.nodeSelectorImaginary pod nodeSelector{}
imaginary.tolerationsImaginary pod tolerations[]
imaginary.resourcesimaginary resources{}
imaginary.securityContextOptional security context for the Imaginary containernil
imaginary.podSecurityContextOptional security context for the Imaginary pod (applies to all containers in the pod)nil
imaginary.service.typeImaginary: Kubernetes Service typeClusterIP
imaginary.service.loadBalancerIPImaginary: LoadBalancerIp for service type LoadBalancernil
imaginary.service.nodePortImaginary: NodePort for service type NodePortnil
imaginary.service.annotationsAdditional annotations for service imaginary{}
imaginary.service.labelsAdditional labels for service imaginary{}

[!Note] You also need to setup nextcloud, to use imaginary

nextcloud:
  defaultConfigs:
    imaginary.config.php: true

imaginary:
  enabled: true

Cron jobs

To execute background tasks by using system cron instead of default Ajax cron, set cronjob.enabled parameter to true. Background jobs are important for tasks that do not necessarily need user intervention, but still need to be executed frequently (cleaning up, sending some notifications, pulling RSS feeds, etc.).

Enabling this option will create a sidecar container in the Nextcloud pod, which will start a crond daemon responsible for running the Nextcloud cron.php script. At first launch, the background jobs mode in your Nextcloud basic settings will automatically be set to Cron.

You can also set cronjob.type to cronjob to instead use a Kubernetes native CronJob. One advantage of this is that it can run as non-root when compared to the crond sidecar.

Using the nextcloud docker image auto-configuration via env vars

The nextcloud/docker image provides an auto-configuration via environment variables. See their docs for more info.

Multiple config.php file

Nextcloud supports loading configuration parameters from multiple files. You can add arbitrary files ending with .config.php in the config/ directory. See documentation. For example, to enable image and document previews:

nextcloud:
  configs:
    previews.config.php: |-
      <?php
      $CONFIG = array (
        'enable_previews' => true,
        'enabledPreviewProviders' => array (
          'OC\Preview\Movie',
          'OC\Preview\PNG',
          'OC\Preview\JPEG',
          'OC\Preview\GIF',
          'OC\Preview\BMP',
          'OC\Preview\XBitmap',
          'OC\Preview\MP3',
          'OC\Preview\MP4',
          'OC\Preview\TXT',
          'OC\Preview\MarkDown',
          'OC\Preview\PDF'
        ),
      );

Using nginx

To use nginx instead of apache to serve nextcloud, Set the following parameters in your values.yaml:

# This Generates an image tag using the chart's app version
# e.g. if the app version is 25.0.3, the image tag will be 25.0.3-fpm
image:
  flavor: fpm
  # You can also specify a tag directly. this version is an example:
  # tag: 25.0.3-fpm
# this deploys an nginx container within the nextcloud pod
nginx
  enabled: true

Service discovery with nginx and ingress

For service discovery (CalDAV, CardDAV, webfinger, nodeinfo) to work you need to add redirects to your ingress. If you use the ingress-nginx you can use the following server snippet annotation:

ingress:
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |-
      server_tokens off;
      proxy_hide_header X-Powered-By;
      rewrite ^/.well-known/webfinger /index.php/.well-known/webfinger last;
      rewrite ^/.well-known/nodeinfo /index.php/.well-known/nodeinfo last;
      rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
      rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json;
      location = /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
      }
      location = /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
      }
      location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
      }
      location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
      }
      location ~ ^/(?:autotest|occ|issue|indie|db_|console) {
        deny all;
      }

Preserving Source IP

ingress:
  annotations:
   nginx.ingress.kubernetes.io/enable-cors: "true"
   nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For"
  configs:
    proxy.config.php: |-
      <?php
      $CONFIG = array (
        'trusted_proxies' => array(
          0 => '127.0.0.1',
          1 => '10.0.0.0/8',
        ),
    'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),
    );

Hugepages

If your node has hugepages enabled, but you do not map any into the container, it could fail to start with a bus error. This is due to your webserver attempting to memory map a file and use hugepages. This can happen in both the apache and fpm images. The fix is to either disable huge pages on the node or map hugepages into the container:

nextcloud:
  extraVolumes:
    - name: hugepages
      emptyDir:
        medium: HugePages-2Mi
  extraVolumeMounts:
    - name: hugepages
      mountPath: /dev/hugepages
resources:
  requests:
    hugepages-2Mi: 500Mi
    # note that Kubernetes currently requires cpu or memory requests and limits before hugepages are allowed.
    memory: 500Mi
  limits:
    # limit and request must be the same for hugepages. They are a fixed resource.
    hugepages-2Mi: 500Mi
    # note that Kubernetes currently requires cpu or memory requests and limits before hugepages are allowed.
    memory: 1Gi

HPA (Clustering)

If you want to have multiple Nextcloud containers, regardless of dynamic or static sizes, you need to use shared persistence between the containers.

Minimum cluster compatible persistence settings:

persistence:
  enabled: true
  accessMode: ReadWriteMany

Adjusting PHP ini values

Sometimes you may need special php.ini values. For instance, perhaps your setup requires a bit more memory. You can add additional php.ini files in the values.yaml by providing nextcloud.phpConfigs.NAME_OF_FILE. Here’s an examples:

nextcloud:
  phpConfigs:
    zz-memory_limit.ini: |-
      memory_limit=512M

[!Note] Be sure to prefix your file name with zz to ensure it is loaded at the end.

Running occ commands

Sometimes you need to run an occ command on the Nextcloud container directly. You can do that by running commands as the user www-data via the kubectl exec command.

# $NEXTCLOUD_POD should be the name of *your* nextcloud pod :)
kubectl exec $NEXTCLOUD_POD -- su -s /bin/sh www-data -c "php occ myocccomand"

Here are some examples below.

Putting Nextcloud into maintanence mode

Some admin actions require you to put your Nextcloud instance into maintanence mode (e.g. backups):

# $NEXTCLOUD_POD should be the name of *your* nextcloud pod :)
kubectl exec $NEXTCLOUD_POD -- su -s /bin/sh www-data -c "php occ maintenance:mode --on"

Downloading models for recognize

Recognize requires you to download models before using it:

# $NEXTCLOUD_POD should be the name of *your* nextcloud pod :)
kubectl exec $NEXTCLOUD_POD -- su -s /bin/sh www-data -c "php occ recognize:download-models"

Backups

Check out the official Nextcloud backup docs. 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 or velero.

Upgrades

Since this chart utilizes the nextcloud/docker image, provided you are using persistent volumes, upgrades of your Nextcloud server are handled automatically 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, you’ll need to make sure you gradually upgrade the helm chart if you have missed serveral app versions.

⚠️ Before Upgrading Nextcloud or the attached database, always make sure you take backups!

After an upgrade, you may have missing indices. To fix this, you can run:

# where NEXTCLOUD_POD is *your* nextcloud pod
kubectl exec -it $NEXTCLOUD_POD -- su -s /bin/sh www-data -c "php occ db:add-missing-indices"

Troubleshooting

Logging

The nextcloud instance deployed by this chart doesn’t currently create a log file locally inside the container. Examples scenarios to change this behavior include:

Changing the logging behavior

To change the logging behavior, modify your logging.config.php in your values.yaml under the nextcloud.configs section like so:

nextcloud:
  configs:
    logging.config.php: |-
      <?php
      $CONFIG = array (
        'log_type' => 'file',
        'logfile' => 'nextcloud.log',
        'loglevel' => 0,
        'logdateformat' => 'F d, Y H:i:s'
        );

loglevel corresponds to the detail of the logs. Valid values are:

01234:::::DIWEFENARABFRRTUONOAG::RL:::AOAcpATltenhlirevaoaitpsctieetyorrinavvssteiuirtcsoyhuns;ctacfotseapheiseudl.s,sme,orbsubtltuotdgweiiotnttashhielawrenaddrsnelfiroinvglgigescienaosgcf.taipnvoditteoinpetesir,aaltpilpournsosbwlcaeormnnsti,inngpusle,u,seprelrruorsrosrf,sataaannlddeffraarttoaarlls.eerrrroorrss..

More information about Nextcloud logging

Viewing the logs

To view logs after changing the logging behavior, you can exec into the Kubernetes pod, or copy them to your local machine.

Exec into the kubernetes pod:

kubectl exec --stdin --tty nextcloud-pod-name-random-chars -- /bin/sh

Then look for the nextcloud.log file with tail or cat:

cat nextcloud.log
tail -f nextcloud.log

Copy the log file to your local machine:

kubectl cp default/nextcloud-pod-name-random-chars:nextcloud.log ./my-local-machine-nextcloud.log

Sharing the logs

Remember to anonymize your logs and snippets from your pod before sharing them with the internet. Kubernetes secrets, even Sealed ones, live in plaintext env variables on your running containers, and log messages can include other information that should stay safely with you.