263 lines
7.5 KiB
YAML
263 lines
7.5 KiB
YAML
apiVersion: helm.toolkit.fluxcd.io/v2
|
|
kind: HelmRelease
|
|
metadata:
|
|
name: nextcloud
|
|
namespace: nextcloud
|
|
spec:
|
|
interval: 30m
|
|
timeout: 15m # Nextcloud init can be slow
|
|
chart:
|
|
spec:
|
|
chart: nextcloud
|
|
version: "8.6.0" # Latest as of Jan 2025
|
|
sourceRef:
|
|
kind: HelmRepository
|
|
name: nextcloud
|
|
namespace: flux-system
|
|
interval: 12h
|
|
install:
|
|
crds: CreateReplace
|
|
remediation:
|
|
retries: 3
|
|
upgrade:
|
|
crds: CreateReplace
|
|
cleanupOnFail: true
|
|
remediation:
|
|
retries: 3
|
|
remediateLastFailure: true
|
|
# CRITICAL: Suspend during major version upgrades to prevent restart loops
|
|
# suspend: true
|
|
values:
|
|
image:
|
|
repository: nextcloud
|
|
tag: 32.0.3-apache # Latest as of Jan 2025. For fresh installs only.
|
|
# UPGRADE PATH: If upgrading from older version, go sequentially:
|
|
# 29.x → 30.0.x → 31.0.x → 32.0.x (one major at a time)
|
|
pullPolicy: IfNotPresent
|
|
|
|
replicaCount: 1 # >1 requires Redis, see below
|
|
|
|
nextcloud:
|
|
host: nextcloud.lab.home.hrajfrisbee.cz # Substitute or hardcode
|
|
# existingSecret: nextcloud-admin # Alternative to inline credentials
|
|
existingSecret:
|
|
enabled: true
|
|
secretName: nextcloud-secrets
|
|
# usernameKey: username
|
|
passwordKey: nextcloud-password
|
|
|
|
username: admin
|
|
# password set via valuesFrom secret
|
|
|
|
|
|
# PHP tuning - critical for stability
|
|
phpConfigs:
|
|
uploadLimit.ini: |
|
|
upload_max_filesize = 16G
|
|
post_max_size = 16G
|
|
max_input_time = 3600
|
|
max_execution_time = 3600
|
|
www-conf.ini: |
|
|
[www]
|
|
pm = dynamic
|
|
pm.max_children = 20
|
|
pm.start_servers = 4
|
|
pm.min_spare_servers = 2
|
|
pm.max_spare_servers = 6
|
|
pm.max_requests = 500
|
|
memory.ini: |
|
|
memory_limit = 1G
|
|
opcache.ini: |
|
|
opcache.enable = 1
|
|
opcache.interned_strings_buffer = 32
|
|
opcache.max_accelerated_files = 10000
|
|
opcache.memory_consumption = 256
|
|
opcache.save_comments = 1
|
|
opcache.revalidate_freq = 60
|
|
; Set to 0 if using ConfigMap-mounted configs
|
|
|
|
configs:
|
|
# Proxy and overwrite settings - CRITICAL for ingress
|
|
proxy.config.php: |-
|
|
<?php
|
|
$CONFIG = array (
|
|
'trusted_proxies' => array(
|
|
0 => '127.0.0.1',
|
|
1 => '10.0.0.0/8',
|
|
2 => '172.16.0.0/12',
|
|
3 => '192.168.0.0/16',
|
|
),
|
|
'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),
|
|
'overwriteprotocol' => 'https',
|
|
);
|
|
|
|
# Performance and maintenance
|
|
custom.config.php: |-
|
|
<?php
|
|
$CONFIG = array (
|
|
'default_phone_region' => 'US',
|
|
'maintenance_window_start' => 1,
|
|
'filelocking.enabled' => true,
|
|
'memcache.local' => '\\OC\\Memcache\\APCu',
|
|
'memcache.distributed' => '\\OC\\Memcache\\Redis',
|
|
'memcache.locking' => '\\OC\\Memcache\\Redis',
|
|
'redis' => array(
|
|
'host' => 'nextcloud-redis-master',
|
|
'port' => 6379,
|
|
'password' => getenv('REDIS_PASSWORD'),
|
|
),
|
|
);
|
|
|
|
extraEnv:
|
|
- name: REDIS_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: nextcloud-secrets
|
|
key: redis-password
|
|
|
|
# Ingress - adjust for your ingress controller
|
|
ingress:
|
|
enabled: true
|
|
className: nginx # or traefik, etc.
|
|
annotations:
|
|
nginx.ingress.kubernetes.io/proxy-body-size: "16G"
|
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
|
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
|
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;
|
|
}
|
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
tls:
|
|
- secretName: nextcloud-tls
|
|
hosts:
|
|
- nextcloud.lab.home.hrajfrisbee.cz
|
|
|
|
# PostgreSQL - strongly recommended over MariaDB for Nextcloud
|
|
postgresql:
|
|
enabled: true
|
|
global:
|
|
postgresql:
|
|
auth:
|
|
username: nextcloud
|
|
database: nextcloud
|
|
existingSecret: nextcloud-secrets
|
|
secretKeys:
|
|
userPasswordKey: postgres-password
|
|
primary:
|
|
persistence:
|
|
enabled: true
|
|
size: 8Gi
|
|
storageClass: "" # Use default or specify
|
|
resources:
|
|
requests:
|
|
memory: 256Mi
|
|
cpu: 100m
|
|
limits:
|
|
memory: 512Mi
|
|
|
|
# Redis - required for file locking and sessions
|
|
redis:
|
|
enabled: true
|
|
auth:
|
|
enabled: true
|
|
existingSecret: nextcloud-secrets
|
|
existingSecretPasswordKey: redis-password
|
|
architecture: standalone
|
|
master:
|
|
persistence:
|
|
enabled: true
|
|
size: 1Gi
|
|
|
|
# Disable built-in databases we're not using
|
|
mariadb:
|
|
enabled: false
|
|
internalDatabase:
|
|
enabled: false
|
|
|
|
externalDatabase:
|
|
enabled: true
|
|
type: postgresql
|
|
host: nextcloud-postgresql # Service name created by subchart
|
|
user: nextcloud
|
|
database: nextcloud
|
|
existingSecret:
|
|
enabled: true
|
|
secretName: nextcloud-secrets
|
|
passwordKey: postgres-password
|
|
|
|
# Cron job - CRITICAL: never use AJAX cron
|
|
cronjob:
|
|
enabled: true
|
|
schedule: "*/5 * * * *"
|
|
resources:
|
|
requests:
|
|
memory: 256Mi
|
|
cpu: 50m
|
|
limits:
|
|
memory: 512Mi
|
|
|
|
# Main persistence
|
|
persistence:
|
|
enabled: true
|
|
storageClass: "" # Specify your storage class
|
|
size: 100Gi
|
|
accessMode: ReadWriteOnce
|
|
# nextcloudData - separate PVC for user data (recommended)
|
|
nextcloudData:
|
|
enabled: true
|
|
storageClass: ""
|
|
size: 500Gi
|
|
accessMode: ReadWriteOnce
|
|
|
|
# Resource limits - tune based on usage
|
|
resources:
|
|
requests:
|
|
cpu: 200m
|
|
memory: 512Mi
|
|
limits:
|
|
memory: 2Gi
|
|
|
|
# Liveness/Readiness - tuned to prevent upgrade restart loops
|
|
livenessProbe:
|
|
enabled: true
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 6
|
|
successThreshold: 1
|
|
readinessProbe:
|
|
enabled: true
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 6
|
|
successThreshold: 1
|
|
startupProbe:
|
|
enabled: true
|
|
initialDelaySeconds: 60
|
|
periodSeconds: 30
|
|
timeoutSeconds: 10
|
|
failureThreshold: 30 # 15 minutes for upgrades
|
|
|
|
# Security context - avoid fsGroup recursive chown
|
|
securityContext:
|
|
fsGroupChangePolicy: OnRootMismatch
|
|
podSecurityContext:
|
|
fsGroup: 33 # www-data
|
|
|
|
# Metrics - optional but recommended
|
|
metrics:
|
|
enabled: false # Enable if you have Prometheus
|
|
# serviceMonitor:
|
|
# enabled: true |