This platform supports three database configurations. Choose based on your needs:
Best for: Getting started, development, small deployments
Each tenant gets their own MariaDB pod managed by the Nextcloud Helm chart.
# In tenant values file
database:
type: mariadb
mariadb:
enabled: true
auth:
database: nextcloud
username: nextcloud
existingSecret: nextcloud-secrets
secretKeys:
password: db-password
primary:
persistence:
enabled: true
size: 8Gi- ✅ Simplest to set up
- ✅ No external dependencies
- ✅ Each tenant fully isolated
- ❌ One database pod per tenant (resource overhead)
- ❌ Database pod can be affected by node upgrades
- ❌ No connection pooling
Best for: When you need PostgreSQL features but don't have external PostgreSQL
Each tenant gets their own PostgreSQL pod with optional custom extensions.
Use tenant-template-postgres.yaml which includes:
- Custom PostgreSQL image with extensions
- Per-tenant Redis
- All necessary secret references
cp values/templates/tenant-template-postgres.yaml values/tenants/tenant-<name>.yaml# In tenant values file
mariadb:
enabled: false
postgresql:
enabled: true
image:
# Custom image with extensions (recommended)
registry: ghcr.io
repository: conductionnl/nextcloud-images
tag: postgres16-ext-sha-6b56bfeda88356d768179c7b2220fb9ded1b4adf
pullPolicy: Always
auth:
database: nextcloud_<tenant>
username: nextcloud
existingSecret: nextcloud-secrets
secretKeys:
adminPasswordKey: postgres-password
userPasswordKey: db-password
primary:
persistence:
enabled: true
size: 8Gi
# Per-tenant Redis (included in postgres template)
redis:
enabled: true
auth:
enabled: true
existingSecret: nextcloud-secrets
existingSecretPasswordKey: redis-passwordThe custom image (conductionnl/nextcloud-images:postgres16-ext-*) includes:
- PostgreSQL 16
- Additional extensions for performance
- Optimized settings for Nextcloud
cd scripts
./create-tenant-secret.sh <tenant-name> --postgres- ✅ PostgreSQL features (better JSON support, etc.)
- ✅ Each tenant fully isolated
- ✅ Custom extensions available
- ✅ Per-tenant Redis (no NetworkPolicy needed)
- ❌ More pods per tenant (PostgreSQL + Redis)
- ❌ Higher resource usage than shared database
Best for: Production, multi-tenant efficiency, managed databases
Shared external PostgreSQL cluster with PgBouncer connection pooling. Databases are automatically provisioned per tenant.
# In tenant values file
database:
type: external
mariadb:
enabled: false
postgresql:
enabled: false
internalDatabase:
enabled: false
externalDatabase:
enabled: true
type: postgresql
host: pgbouncer.nextcloud-platform.svc.cluster.local
port: 5432
database: nextcloud_<tenant-name>
existingSecret:
enabled: true
secretName: nextcloud-secrets
usernameKey: db-username
passwordKey: db-password- External PostgreSQL server accessible from cluster
- PostgreSQL admin secret for auto-provisioning:
export POSTGRES_HOST='your-postgres-host'
export POSTGRES_PORT='5432'
export POSTGRES_ADMIN_USER='postgres'
export POSTGRES_ADMIN_PASSWORD='your-admin-password'
./scripts/create-postgres-admin-secret.shWhen using external PostgreSQL, a Job automatically:
- Creates database
nextcloud_<tenant-name> - Creates user
nextcloud_<tenant-name> - Grants all necessary privileges
- ✅ Most efficient for multi-tenant
- ✅ Connection pooling via PgBouncer
- ✅ Can use managed PostgreSQL (RDS, Cloud SQL, etc.)
- ✅ Better resilience (database survives cluster issues)
- ❌ Requires external PostgreSQL setup
- ❌ More complex initial setup
-
Export data from MariaDB:
kubectl exec -n nc-$TENANT deploy/nextcloud -- php occ maintenance:mode --on # Use mysqldump or Nextcloud's backup app
-
Update tenant values to use external PostgreSQL
-
Sync with Argo CD (creates new database)
-
Import data to PostgreSQL
-
Disable maintenance mode
For production, consider CloudNativePG:
# Future: operator-managed PostgreSQL
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: nextcloud-postgres
spec:
instances: 3
storage:
size: 100GiThis provides:
- High availability (automatic failover)
- Backups to S3
- Point-in-time recovery
- Rolling updates
| Feature | MariaDB | PostgreSQL In-Cluster | External PostgreSQL |
|---|---|---|---|
| Template | tenant-template.yaml |
tenant-template-postgres.yaml |
(custom) |
| Setup complexity | Easy | Easy | Medium |
| Resource efficiency | Medium | Low (includes Redis) | High |
| Connection pooling | No | No | Yes (PgBouncer) |
| Custom extensions | No | Yes | Depends |
| NetworkPolicy needed | Yes (platform Redis) | No (per-tenant Redis) | Yes |
| Node upgrade resilience | Medium | Medium | High |
| Multi-tenant efficiency | Medium | Low | High |
| Managed DB support | No | No | Yes |
| Recommended for | Simple deployments | PostgreSQL features | Production |
| I want... | Use this template |
|---|---|
| Simplest setup | tenant-template.yaml (MariaDB) |
| PostgreSQL with extensions | tenant-template-postgres.yaml |
| Shared database cluster | External PostgreSQL (custom setup) |