Database Options
This platform supports three database configurations. Choose based on your needs.
DB config is layered: each profile lives in
values/db/<dbType>.yaml(mariadb,postgres,external) and is selected bytenant.dbTypein the tenant file. The blocks below are illustrative excerpts of those profiles — seevalues/db/for the authoritative values anddocs/ARCHITECTURE.mdfor how the ApplicationSet wires them together.
Option 1: MariaDB (Default - Simplest)
Best for: Getting started, development, small deployments
Each tenant gets their own MariaDB pod managed by the Nextcloud Helm chart.
Configuration
Set tenant.dbType: mariadb (the default) in the tenant file; the matching
profile values/db/mariadb.yaml is then layered in automatically. Illustrative
excerpt of that profile:
# values/db/mariadb.yaml (excerpt)
mariadb:
enabled: true
auth:
existingSecret: nextcloud-secrets
secretKeys:
mariadb-root-password: mariadb-root-password
mariadb-password: mariadb-password
Pros
- ✅ Simplest to set up
- ✅ No external dependencies
- ✅ Each tenant fully isolated
Cons
- ❌ One database pod per tenant (resource overhead)
- ❌ Database pod can be affected by node upgrades
- ❌ No connection pooling
Option 2: PostgreSQL In-Cluster
Best for: When you need PostgreSQL features but don't have external PostgreSQL
Each tenant gets their own PostgreSQL pod with optional custom extensions.
Template
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
Configuration
# In tenant values file
mariadb:
enabled: false
postgresql:
enabled: true
image:
# Custom image with extensions (recommended).
# Example tag — check values/db/postgres.yaml for the current tag/digest.
registry: docker.io
repository: conduction2022/nextcloud-images
tag: postgres16-ext-sha-8abef67
pullPolicy: IfNotPresent
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-password
Custom PostgreSQL Image
The custom image (conduction2022/nextcloud-images:postgres16-ext-*) includes:
- PostgreSQL 16
- Additional extensions for performance
- Optimized settings for Nextcloud
Secret Creation
cd scripts
./create-tenant-secret.sh <tenant-name> --postgres
Pros
- ✅ PostgreSQL features (better JSON support, etc.)
- ✅ Each tenant fully isolated
- ✅ Custom extensions available
- ✅ Per-tenant Redis (no NetworkPolicy needed)
Cons
- ❌ More pods per tenant (PostgreSQL + Redis)
- ❌ Higher resource usage than shared database
Option 3: External PostgreSQL (Production)
Best for: Production, multi-tenant efficiency, managed databases
Shared external PostgreSQL cluster with PgBouncer connection pooling. Databases are automatically provisioned per tenant.
Configuration
Set tenant.dbType: external in the tenant file; the matching profile
values/db/external.yaml is then layered in automatically. Illustrative excerpt
of that profile (host/port are typically set in values/env/*.yaml):
# values/db/external.yaml (excerpt)
mariadb:
enabled: false
postgresql:
enabled: false
internalDatabase:
enabled: false
externalDatabase:
enabled: true
type: postgresql
existingSecret:
enabled: true
secretName: nextcloud-secrets
usernameKey: db-username
passwordKey: db-password
Prerequisites
- 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.sh
What's Automated
When using external PostgreSQL, a Job automatically:
- Creates database nextcloud_<tenant-name>
- Creates user nextcloud_<tenant-name>
- Grants all necessary privileges
Pros
- ✅ Most efficient for multi-tenant
- ✅ Connection pooling via PgBouncer
- ✅ Can use managed PostgreSQL (RDS, Cloud SQL, etc.)
- ✅ Better resilience (database survives cluster issues)
Cons
- ❌ Requires external PostgreSQL setup
- ❌ More complex initial setup
Migrating Between Options
MariaDB → External PostgreSQL
-
Export data from MariaDB:
bash kubectl exec -n "$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
Using CloudNativePG Operator (Future — NOT implemented)
⚠️ Aspirational / not implemented. This section describes a possible future direction only. None of the below is wired into the platform today — do not follow it as current guidance. The three options above are the supported set.
For production, one option to consider is CloudNativePG:
# Future / NOT implemented: operator-managed PostgreSQL
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: nextcloud-postgres
spec:
instances: 3
storage:
size: 100Gi
This provides: - High availability (automatic failover) - Backups to S3 - Point-in-time recovery - Rolling updates
Comparison Table
| 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 |
Quick Reference
| 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) |