apiVersion: v1 kind: ConfigMap metadata: name: nextcloud-ldap-client-config namespace: nextcloud data: ldap.conf: | TLS_REQCERT ALLOW --- apiVersion: v1 kind: ConfigMap metadata: name: nextcloud-ldap-bootstrap namespace: nextcloud data: 20-ldap-bootstrap.sh: | #!/bin/sh set -eu cd /var/www/html echo "[ldap-bootstrap] waiting for Nextcloud to be installed..." i=0 until php occ status >/tmp/occ-status.txt 2>/dev/null; do i=$((i+1)) if [ "$i" -gt 120 ]; then echo "[ldap-bootstrap] timeout waiting for occ status" exit 1 fi sleep 2 done if ! grep -q "installed: true" /tmp/occ-status.txt; then echo "[ldap-bootstrap] Nextcloud not installed yet, skipping LDAP bootstrap for this start" exit 0 fi echo "[ldap-bootstrap] enabling user_ldap app" php occ app:enable user_ldap || true LDAP_CONFIG_ID="${LDAP_CONFIG_ID:-s01}" if php occ ldap:show-config "${LDAP_CONFIG_ID}" >/tmp/ldap-show.txt 2>/dev/null; then echo "[ldap-bootstrap] using existing LDAP config ${LDAP_CONFIG_ID}" else echo "[ldap-bootstrap] creating LDAP config" php occ ldap:create-empty-config >/tmp/ldap-create.txt 2>&1 || true cat /tmp/ldap-create.txt if ! php occ ldap:show-config "${LDAP_CONFIG_ID}" >/tmp/ldap-show.txt 2>/dev/null; then echo "[ldap-bootstrap] LDAP config ${LDAP_CONFIG_ID} not found after creation attempt" echo "[ldap-bootstrap] existing configs:" php occ ldap:show-config || true exit 1 fi fi set_cfg() { key="$1" value="$2" php occ ldap:set-config "${LDAP_CONFIG_ID}" "${key}" "${value}" } echo "[ldap-bootstrap] applying LDAP settings" set_cfg ldapHost "${LDAP_HOST}" set_cfg ldapPort "${LDAP_PORT}" set_cfg ldapBase "${LDAP_BASE_DN}" set_cfg ldapBackupHost "${LDAP_BACKUP_HOST}" set_cfg ldapBackupPort "${LDAP_PORT}" set_cfg ldapBaseUsers "${LDAP_USER_BASE_DN}" set_cfg ldapBaseGroups "${LDAP_GROUP_BASE_DN}" set_cfg ldapAgentName "${LDAP_BIND_DN}" set_cfg ldapAgentPassword "${LDAP_BIND_PASSWORD}" set_cfg ldapLoginFilter "(&(objectClass=user)(sAMAccountName=%uid))" set_cfg ldapUserFilter "(|(|(memberof=CN=undercloud-users,OU=groups,OU=Undercloud,DC=undercloud,DC=local)(primaryGroupID=1103)))" set_cfg ldapUserDisplayName "cn" set_cfg ldapEmailAttribute "mail" set_cfg ldapGroupFilter "(&(objectClass=group)(cn=*))" set_cfg ldapGroupDisplayName "cn" set_cfg ldapGroupMemberAssocAttr "member" set_cfg ldapExpertUUIDUserAttr "objectGUID" set_cfg ldapExpertUUIDGroupAttr "objectGUID" set_cfg ldapExpertUsernameAttr "sAMAccountName" set_cfg ldapConfigurationActive "1" set_cfg turnOffCertCheck "1" set_cfg ldapTLS "0" set_cfg ldapAdminGroup "nextcloud-admins" set_cfg ldapNestedGroups "1" echo "[ldap-bootstrap] testing LDAP config ${LDAP_CONFIG_ID}" if php occ ldap:test-config "${LDAP_CONFIG_ID}"; then echo "[ldap-bootstrap] LDAP config OK" else echo "[ldap-bootstrap] disabling user_ldap app" php occ app:disable user_ldap || true php occ ldap:set-config "${LDAP_CONFIG_ID}" ldapConfigurationActive 0 || true fi 30-files-external-bootstrap.sh: | #!/bin/sh set -eu cd /var/www/html echo "[files-external-bootstrap] waiting for Nextcloud to be installed..." i=0 until php occ status >/tmp/occ-status.txt 2>/dev/null; do i=$((i+1)) if [ "$i" -gt 120 ]; then echo "[files-external-bootstrap] timeout waiting for occ status" exit 1 fi sleep 2 done if ! grep -q "installed: true" /tmp/occ-status.txt; then echo "[files-external-bootstrap] Nextcloud not installed yet, skipping for this start" exit 0 fi echo "[files-external-bootstrap] enabling files_external app" php occ app:enable files_external || true # Ensure the directories exist and are writable by www-data mkdir -p /data/data /data/music /data/movies chown -R 33:33 /data/data /data/music /data/movies chmod -R u+rwX,g+rwX /data/data /data/music /data/movies mount_exists() { mount_point="$1" php occ files_external:list | grep -F " ${mount_point} " >/dev/null 2>&1 } create_local_mount() { mount_point="$1" source_path="$2" if mount_exists "${mount_point}"; then echo "[files-external-bootstrap] mount ${mount_point} already exists" else echo "[files-external-bootstrap] creating local mount ${mount_point} -> ${source_path}" php occ files_external:create "${mount_point}" local null::null -c datadir="${source_path}" fi } create_local_mount "/data" "/data/data" create_local_mount "/music" "/data/music" create_local_mount "/movies" "/data/movies" echo "[files-external-bootstrap] current external mounts:" php occ files_external:list || true 40-office-bootstrap.sh: | #!/bin/sh set -eu cd /var/www/html echo "[office-bootstrap] waiting for Nextcloud to be installed..." i=0 until php occ status >/tmp/occ-status.txt 2>/dev/null; do i=$((i+1)) if [ "$i" -gt 120 ]; then echo "[office-bootstrap] timeout waiting for occ status" exit 1 fi sleep 2 done if ! grep -q "installed: true" /tmp/occ-status.txt; then echo "[office-bootstrap] Nextcloud not installed yet, skipping for this start" exit 0 fi echo "[office-bootstrap] enabling richdocuments app" php occ app:enable richdocuments || true # External Collabora server php occ config:app:set richdocuments wopi_url --value="https://collabora.apps.undercloud.dev" # Optional but useful when reverse proxies are involved php occ config:app:set richdocuments public_wopi_url --value="https://nextcloud.apps.undercloud.dev" # Your instance is behind a reverse proxy and has a single canonical URL php occ config:app:set richdocuments canonical_webroot --value="https://nextcloud.apps.undercloud.dev" # Do not disable certificate verification for a proper public HTTPS setup php occ config:app:delete richdocuments disable_certificate_verification || true echo "[office-bootstrap] resulting Office config:" php occ config:app:get richdocuments wopi_url || true php occ config:app:get richdocuments public_wopi_url || true php occ config:app:get richdocuments canonical_webroot || true --- apiVersion: v1 kind: ConfigMap metadata: name: nextcloud-config namespace: nextcloud data: redis.config.php: | true, 'memcache.local' => '\OC\Memcache\APCu', 'memcache.locking' => '\OC\Memcache\Redis', 'redis' => array( 'host' => 'redis', 'port' => 6379, ), ); reverse-proxy.config.php: | array( 0 => '10.0.0.0/16', 1 => 'fd00::/16', 2 => '2001::/16', ), 'overwritehost' => 'nextcloud.apps.undercloud.dev', 'overwriteprotocol' => 'https', 'overwrite.cli.url' => 'https://nextcloud.apps.undercloud.dev', ); --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nextcloud namespace: nextcloud spec: accessModes: - ReadWriteMany resources: requests: storage: 64Gi storageClassName: cephfs-hyper --- apiVersion: apps/v1 kind: Deployment metadata: name: nextcloud namespace: nextcloud spec: replicas: 1 selector: matchLabels: app: nextcloud template: metadata: labels: app: nextcloud spec: dnsPolicy: None dnsConfig: nameservers: - 2001:470:7116:f:1::53 searches: - nextcloud.svc.k8s.undercloud.local - svc.k8s.undercloud.local - k8s.undercloud.local - undercloud.local options: - name: ndots value: "1" securityContext: fsGroup: 33 fsGroupChangePolicy: OnRootMismatch initContainers: - name: fix-permissions image: busybox:1.36 command: - sh - -c - | set -e mkdir -p /var/www/html/config /var/www/html/data /var/www/html/custom_apps chown -R 33:33 /var/www/html chmod -R u+rwX,g+rwX /var/www/html volumeMounts: - name: nextcloud mountPath: /var/www/html containers: - name: nextcloud image: nextcloud:apache #imagePullPolicy: IfNotPresent imagePullPolicy: Always ports: - containerPort: 80 env: - name: MYSQL_DATABASE value: "nextcloud" - name: MYSQL_HOST value: "db" - name: MYSQL_USER valueFrom: secretKeyRef: name: nextcloud-db key: username - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: nextcloud-db key: user.pw - name: NEXTCLOUD_ADMIN_USER value: "admin" - name: NEXTCLOUD_ADMIN_PASSWORD valueFrom: secretKeyRef: name: nextcloud-admin key: pw - name: NEXTCLOUD_DATA_DIR value: "/var/www/html/data" - name: NEXTCLOUD_TRUSTED_DOMAINS value: "nextcloud.apps.undercloud.dev nextcloud.nextcloud.svc.k8s.undercloud.local" - name: LDAP_CONFIG_ID value: "s01" - name: LDAP_HOST value: "ldaps://dc1.undercloud.local" - name: LDAP_BACKUP_HOST value: "ldaps://dc2.undercloud.local" - name: LDAP_PORT value: "636" - name: LDAP_BASE_DN value: "dc=undercloud,dc=local" - name: LDAP_USER_BASE_DN value: "ou=users,ou=Undercloud,dc=undercloud,dc=local" - name: LDAP_GROUP_BASE_DN value: "ou=groups,ou=Undercloud,dc=undercloud,dc=local" - name: LDAP_BIND_DN value: "CN=nextcloud,OU=serviceaccounts,OU=users,OU=Undercloud,DC=undercloud,DC=local" - name: LDAP_BIND_PASSWORD valueFrom: secretKeyRef: name: nextcloud-ldap key: bindPassword volumeMounts: - name: nextcloud mountPath: /var/www/html - name: nextcloud-config mountPath: /var/www/html/config/redis.config.php subPath: redis.config.php - name: nextcloud-config mountPath: /var/www/html/config/reverse-proxy.config.php subPath: reverse-proxy.config.php - name: ldap-bootstrap mountPath: /docker-entrypoint-hooks.d/before-starting/20-ldap-bootstrap.sh subPath: 20-ldap-bootstrap.sh - name: ldap-bootstrap mountPath: /docker-entrypoint-hooks.d/before-starting/30-files-external-bootstrap.sh subPath: 30-files-external-bootstrap.sh - name: ldap-bootstrap mountPath: /docker-entrypoint-hooks.d/before-starting/40-office-bootstrap.sh subPath: 40-office-bootstrap.sh - name: movies mountPath: /data/movies - name: music mountPath: /data/music - name: data mountPath: /data/data - name: tvshows mountPath: /data/tvshows - name: ldap-client-config mountPath: /etc/ldap/ldap.conf subPath: ldap.conf readOnly: true volumes: - name: nextcloud persistentVolumeClaim: claimName: nextcloud - name: nextcloud-config configMap: name: nextcloud-config items: - key: redis.config.php path: redis.config.php - key: reverse-proxy.config.php path: reverse-proxy.config.php - name: ldap-bootstrap configMap: name: nextcloud-ldap-bootstrap defaultMode: 0755 - name: movies persistentVolumeClaim: claimName: movies - name: music persistentVolumeClaim: claimName: music - name: tvshows persistentVolumeClaim: claimName: tvshows - name: data persistentVolumeClaim: claimName: data - name: ldap-client-config configMap: name: nextcloud-ldap-client-config items: - key: ldap.conf path: ldap.conf --- apiVersion: v1 kind: Service metadata: name: nextcloud namespace: nextcloud labels: app: nextcloud spec: internalTrafficPolicy: Cluster ipFamilies: - IPv6 #- IPv4 ipFamilyPolicy: SingleStack type: ClusterIP selector: app: nextcloud ports: - name: http port: 80 protocol: TCP targetPort: 80