Nextcloud¶
Self-Hosted File Sync and Collaboration Platform
Nextcloud provides secure file storage, sharing, and collaboration with integrated office editing and real-time collaboration tools.
Overview¶
The Nextcloud deployments provide:
Nextcloud Hub (31.0.13) - File sync, sharing, and collaboration
Collabora Online - Browser-based document editing (LibreOffice)
Whiteboard - Real-time collaborative whiteboard
S3 Primary Storage - Hetzner Object Storage for files
CloudNativePG PostgreSQL - High-availability database with automated backups
Redis - Caching and session management
ArgoCD GitOps Management - Deployed from dp-kup/internal/nextcloud
CDK8S Infrastructure as Code - TypeScript-based manifest generation with shared constructs
Active Instances¶
nextcloudkup¶
URL: https://cloud.kup6s.com
Purpose: Internal kup6s team file storage
Namespace:
nextcloudkupReplicas: 3 (load balanced)
Storage: Hetzner S3 fsn1
nextcloudaffenstall¶
URL: https://affenstall.cloud
Purpose: Production instance for affenstall.cloud users
Namespace:
nextcloudaffenstallReplicas: 1 (RWO volume constraint)
Storage: Hetzner S3 fsn1
Migrated: January 2026 from Docker Swarm to Kubernetes
Key Features¶
File Management¶
WebDAV protocol for desktop/mobile sync
Shared folders and public links
File versioning and retention
Selective sync and virtual files
Full-text search
Collaboration¶
Collabora Online - Real-time document editing (Word, Excel, PowerPoint compatible)
Whiteboard - Digital whiteboard with shared drawing canvas
Comments and annotations on files
Activity feed for file changes
Security¶
End-to-end encryption for sensitive files
Two-factor authentication (TOTP)
Server-side encryption at rest (S3)
Brute-force protection
File access audit logs
Integration¶
External storage mounts (SMB, WebDAV, S3)
LDAP/AD authentication (optional)
Prometheus metrics endpoint
App ecosystem (Calendar, Contacts, Talk, etc.)
Quick Start¶
Check Deployment Status¶
# Check pods for an instance
kubectl get pods -n nextcloudkup
kubectl get pods -n nextcloudaffenstall
# Check ArgoCD sync status
kubectl get application -n argocd | grep nextcloud
# View pod logs
kubectl logs -n nextcloudkup deploy/nextcloud --tail=50
Run occ Commands¶
# Check Nextcloud status
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ status
# List installed apps
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ app:list
# Scan files
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ files:scan --all
# Check database connection
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ config:list system
Access Admin Interface¶
Navigate to instance URL (e.g., https://cloud.kup6s.com)
Log in with admin credentials (from
nextcloudsecret)Settings → Administration → Overview for system status
Architecture¶
The Nextcloud deployment uses a shared CDK8S package architecture for consistency across instances:
dp-kup/internal/nextcloud/
├── packages/nextcloud-shared/ # Shared CDK8S constructs
│ └── src/
│ ├── nextcloud-helm.ts # Nextcloud Helm chart wrapper
│ ├── postgres.ts # CloudNativePG cluster
│ ├── redis.ts # Redis StatefulSet
│ ├── collabora.ts # Collabora Office deployment
│ ├── whiteboard.ts # Whiteboard deployment
│ ├── s3-buckets.ts # Crossplane S3 bucket CRDs
│ └── s3-credentials.ts # ESO secret from Infisical
├── nextcloudkup/ # Instance: cloud.kup6s.com
│ ├── config.yaml # Instance-specific configuration
│ ├── charts/nextcloud-chart.ts # Orchestrates shared constructs
│ └── manifests/ # Generated K8s manifests
└── nextcloudaffenstall/ # Instance: affenstall.cloud
├── config.yaml
├── charts/nextcloud-chart.ts
└── manifests/
Each instance uses the same constructs but different configuration (config.yaml).
ArgoCD Sync Waves¶
Resources are deployed in ordered waves:
Wave |
Components |
Purpose |
|---|---|---|
0 |
Namespace |
Create namespace first |
1 |
S3 buckets (Crossplane), S3 credentials (ESO) |
External dependencies (~60s) |
2 |
PostgreSQL (CNPG), Redis |
Data layer (~3-5 min) |
3 |
PgBouncer pooler |
Connection pooling |
4 |
Nextcloud, Collabora, Whiteboard |
Application layer |
Storage Architecture¶
S3 Primary Storage (Hetzner)¶
All user files stored in S3 object storage:
Bucket naming:
data-{instance}-kup6s(e.g.,data-nextcloudkup-kup6s)Endpoint: https://fsn1.your-objectstorage.com
Region: fsn1 (Falkenstein, Germany)
Credentials: Injected from Kubernetes secret via environment variables
Access: Direct from Nextcloud PHP code (no FUSE mount)
PostgreSQL Data (CloudNativePG)¶
Database metadata stored in Longhorn volumes:
PVC size: 10Gi per instance
Storage class:
longhornReplicas: 2 (primary + replica)
Backups: Automated to S3 via Barman Cloud Plugin
Nextcloud Local Storage (Longhorn)¶
Persistent volume for config and temporary files:
PVC size: 5Gi
Storage class:
longhornAccess mode: RWO (ReadWriteOnce)
Content:
config/,apps/,tmp/, themesNote: User data NOT stored here (in S3 instead)
Common Operations¶
Scale Nextcloud Replicas¶
# In config.yaml
replicas:
nextcloud: 3 # Requires RWX storage or 1 replica for RWO
postgres: 2
redis: 1
Important: Nextcloud uses RWO volumes, so only 1 replica supported unless migrating to SMB CSI (RWX).
Update Nextcloud Version¶
# In config.yaml
versions:
nextcloud: "31.0.14" # Update version
Then regenerate and commit:
cd dp-kup/internal/nextcloud/{instance}
npm run synth
git add manifests/
git commit -m "update: Nextcloud to 31.0.14"
git push
ArgoCD auto-syncs changes.
Add/Remove Apps¶
# Install app
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ app:install calendar
# Remove app
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ app:remove calendar
# List available apps
kubectl exec -n nextcloudkup deploy/nextcloud -- php occ app:list
Database Maintenance¶
# Vacuum PostgreSQL
kubectl exec -n nextcloudkup nextcloud-postgres-1 -- psql -U postgres -d nextcloud -c "VACUUM ANALYZE;"
# Check database size
kubectl exec -n nextcloudkup nextcloud-postgres-1 -- psql -U postgres -d nextcloud -c "SELECT pg_size_pretty(pg_database_size('nextcloud'));"
Troubleshooting¶
Pods Stuck in CrashLoopBackOff¶
Check logs for specific errors:
kubectl logs -n nextcloudkup deploy/nextcloud --previous
Common issues:
S3 credentials missing or incorrect
PostgreSQL not ready
Config.php corruption
Internal Server Error After Login¶
Usually S3 credential issues. Verify:
# Check S3 credentials exist
kubectl get secret -n nextcloudkup nextcloud-s3-credentials -o yaml
# Check credentials in Nextcloud config
kubectl exec -n nextcloudkup deploy/nextcloud -- \
php occ config:list system --private | jq '.system.objectstore.arguments'
404 or 503 Errors¶
Check Traefik routing:
# Verify Ingress exists
kubectl get ingress -n nextcloudkup
# Check for conflicting Ingresses
kubectl get ingress -A | grep "{domain}"
# Check Traefik logs
kubectl logs -n traefik deployment/traefik | grep nextcloud
Files Not Accessible¶
Run file scan to sync S3 with database:
kubectl exec -n nextcloudkup deploy/nextcloud -- \
php occ files:scan --all