Customize Storage¶
How to adjust PersistentVolumeClaim sizes and storage classes for Mailu components.
Problem¶
You need to customize storage sizes for mailboxes, queues, and other persistent data based on your expected user count, email volume, or available storage classes.
Solution¶
The MailuChart accepts a storage configuration object that controls PVC sizes and storage classes for each component. Configure a global storage class and override sizes per component.
Understanding Storage Requirements¶
Different Mailu components have different storage needs:
Component |
Purpose |
Typical Size |
Growth Rate |
|---|---|---|---|
Dovecot |
User mailboxes (largest) |
50-500Gi |
1-5GB per active user |
Postfix |
Mail queue |
5-10Gi |
Temporary, self-cleaning |
Rspamd |
Spam learning data |
5Gi |
Slow growth |
Admin |
DKIM keys, config |
5Gi |
Minimal growth |
ClamAV |
Virus signatures |
5Gi |
Periodic updates |
Webdav |
Calendars, contacts |
5-20Gi |
50-200MB per user |
Set Global Storage Class¶
Configure a default storage class for all components:
import { App } from 'cdk8s';
import { MailuChart } from 'cdk8s-mailu';
const app = new App();
new MailuChart(app, 'mailu', {
namespace: 'mailu',
domain: 'example.com',
hostnames: ['mail.example.com'],
subnet: '10.42.0.0/16',
// ... other config ...
storage: {
storageClass: 'longhorn', // Applied to all components
},
});
app.synth();
Common storage classes:
longhorn- Longhorn distributed storage (recommended for production)local-path- K3s default local storage (testing only)standard- Cloud provider defaultgp2,gp3- AWS EBSpd-standard,pd-ssd- GCP Persistent Disk
Customize Component Storage Sizes¶
Small Deployment (< 50 users)¶
Minimal storage footprint for personal or small team use:
storage: {
storageClass: 'longhorn',
admin: { size: '5Gi' }, // Default
postfix: { size: '5Gi' }, // Default
dovecot: { size: '50Gi' }, // ~1GB per user
rspamd: { size: '5Gi' }, // Default
},
Medium Deployment (50-500 users)¶
Scale mailbox storage for more users:
storage: {
storageClass: 'longhorn',
admin: { size: '5Gi' },
postfix: { size: '10Gi' }, // Larger queue for volume
dovecot: { size: '200Gi' }, // ~4GB per user average
rspamd: { size: '10Gi' }, // More spam learning data
},
Large Deployment (500+ users)¶
Production-scale storage with capacity planning:
storage: {
storageClass: 'longhorn',
admin: { size: '10Gi' },
postfix: { size: '20Gi' },
dovecot: { size: '1000Gi' }, // Plan for 2GB per user
rspamd: { size: '20Gi' },
},
Override Storage Class Per Component¶
Use different storage classes for different performance tiers:
storage: {
// Default storage class (standard tier)
storageClass: 'longhorn',
// High-performance storage for mailboxes (SSD-backed)
dovecot: {
size: '200Gi',
storageClass: 'longhorn-fast', // Override with faster class
},
// Standard storage for queues and caches
postfix: { size: '10Gi' }, // Uses default 'longhorn'
rspamd: { size: '10Gi' }, // Uses default 'longhorn'
},
Use cases for per-component storage classes:
Fast SSDs for Dovecot mailboxes (high IOPS)
Standard disks for Postfix queue (temporary data)
Cheaper storage for backups
Enable Optional Component Storage¶
When enabling optional components, configure their storage:
components: {
clamav: true,
webdav: true,
},
storage: {
storageClass: 'longhorn',
// Required for enabled optional components
clamav: { size: '10Gi' }, // Virus signature database
webdav: { size: '20Gi' }, // Calendars and contacts
},
Expand Existing PVCs¶
Important: PVC sizes can be increased but never decreased. Shrinking requires deleting and recreating the PVC (data loss).
Step 1: Update configuration¶
Increase the size in your CDK8S configuration:
storage: {
storageClass: 'longhorn',
dovecot: { size: '500Gi' }, // Increased from 200Gi
},
Step 2: Regenerate and apply¶
# Regenerate manifests with new size
npm run synth
# Apply changes
kubectl apply -f dist/mailu.k8s.yaml
Step 3: Verify expansion¶
# Check PVC status
kubectl get pvc -n mailu
# Verify new size (should show RESIZING or new size)
kubectl describe pvc -n mailu mailu-dovecot-pvc
Note: The storage class must support volume expansion (allowVolumeExpansion: true). Check with:
kubectl get storageclass <storage-class-name> -o yaml | grep allowVolumeExpansion
Storage Performance Optimization¶
Longhorn Replica Configuration¶
For Longhorn storage, consider replica settings based on data criticality:
High availability (mailboxes):
3 replicas across nodes
Use
longhornstorage class with 2-3 replicas
Standard reliability (queues, caches):
2 replicas
Use default
longhornstorage class
Single replica (temporary data):
1 replica
Lower storage overhead
Not recommended for mailboxes
Note: Replica configuration is set at the storage class level, not per-PVC.
Monitor Storage Usage¶
Track storage consumption to plan capacity:
# Check PVC usage
kubectl get pvc -n mailu
# Detailed usage per pod
kubectl exec -n mailu <dovecot-pod-name> -- df -h /mail
# Check available capacity on nodes (Longhorn)
kubectl get nodes.longhorn.io -n longhorn-system
Set up monitoring alerts at 70% and 85% capacity thresholds.
Troubleshooting¶
PVC stuck in Pending¶
Symptom: PVC shows Pending status, pod cannot start.
Solution: Check storage class exists and has available capacity.
# Check PVC status
kubectl describe pvc -n mailu <pvc-name>
# Check storage class
kubectl get storageclass
# Check node storage capacity (Longhorn)
kubectl get nodes.longhorn.io -n longhorn-system
PVC expansion not working¶
Symptom: PVC size unchanged after applying new configuration.
Solution: Verify storage class supports expansion:
# Check storage class expansion support
kubectl get storageclass <storage-class-name> -o jsonpath='{.allowVolumeExpansion}'
# If false, expansion is not supported
# Alternative: Create new PVC with larger size and migrate data
Out of storage space¶
Symptom: Pods show disk pressure, writes failing.
Immediate fix: Increase PVC size (see expansion section above).
Long-term:
Set up storage monitoring and alerting
Review mailbox quotas in Mailu admin UI
Enable email compression in Dovecot
Implement email retention policies
Estimate Storage Requirements¶
Calculating Dovecot mailbox storage¶
Formula: Total Storage = (Active Users × Average MB per User × Growth Factor) + Buffer
Example (100 users):
Active users: 100
Average per user: 3GB (typical)
Growth factor: 1.5 (50% growth over 2 years)
Buffer: 20% (for spikes)
Calculation: (100 × 3GB × 1.5) + 20% = 450GB × 1.2 = 540GB
Recommended: 600Gi PVC
Monitoring actual usage¶
Deploy with initial estimates, then adjust based on actual usage:
# Check current mailbox usage
kubectl exec -n mailu <dovecot-pod> -- du -sh /mail
# Per-user breakdown (if accessible)
kubectl exec -n mailu <dovecot-pod> -- du -sh /mail/*
See Also¶
Component Specifications - Default storage sizes
Scale Resources - Adjust CPU/memory
Enable Optional Components - Add components requiring storage