Skip to content

Commit e8582ae

Browse files
mitchrossclaude
andcommitted
docs: update storage architecture for tiered backup and volume populator
- Update backup schedules: critical (hourly) vs non-critical (daily) - Document Volume Populator pattern for automatic restore - Update secrets doc for RustFS (replaced MinIO references) - Add secret structure example for ExternalSecrets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 73ad207 commit e8582ae

2 files changed

Lines changed: 84 additions & 48 deletions

File tree

docs/secrets/volsync-secrets.md

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
## Required 1Password Items
44

5-
Before VolSync backups will work, you need to create one new item in 1Password.
5+
Before VolSync backups will work, you need the `rustfs` item in 1Password.
66

7-
### volsync-kopia
7+
### rustfs
88

9-
Create a new **Password** item in your 1Password vault:
9+
Create a **Password** item in your 1Password vault:
1010

1111
| Field | Value |
1212
|-------|-------|
13-
| **Item name** | `volsync-kopia` |
14-
| **Field name** | `password` |
15-
| **Value** | A strong random password (32+ characters) |
13+
| **Item name** | `rustfs` |
14+
| **access_key** | RustFS access key |
15+
| **secret_key** | RustFS secret key |
16+
| **restic_password** | A strong random password (32+ characters) |
1617

17-
This password encrypts all Kopia/Restic backup repositories stored in S3.
18+
The `restic_password` encrypts all backup repositories stored in S3.
1819

1920
**Generate a secure password:**
2021
```bash
@@ -23,41 +24,46 @@ openssl rand -base64 32
2324

2425
Example output: `K7x9mP2nL4qR8vT1wY5zA3cF6hJ0bN+dG=`
2526

26-
### Existing Items Used
27-
28-
The VolSync configuration also uses your existing `minio` item:
29-
30-
| Item | Fields Used |
31-
|------|-------------|
32-
| `minio` | `minio_access_key`, `minio_secret_key` |
33-
34-
These should already exist from your Longhorn backup configuration.
35-
3627
## Verification
3728

38-
After creating the `volsync-kopia` item, verify the ExternalSecrets are syncing:
29+
After creating the `rustfs` item, verify the ExternalSecrets are syncing:
3930

4031
```bash
41-
# Check VolSync system secret
42-
kubectl get externalsecret -n volsync-system
43-
4432
# Check app-level secrets (example)
4533
kubectl get externalsecret -n home-assistant
34+
35+
# View secret details
36+
kubectl get externalsecret home-assistant-volsync-secret -n home-assistant -o yaml
4637
```
4738

4839
All ExternalSecrets should show `SecretSynced` status.
4940

5041
## S3 Bucket Setup
5142

52-
Ensure these buckets exist in your RustFS/MinIO (192.168.10.133):
43+
Ensure the `volsync` bucket exists in RustFS (192.168.10.133:30292):
5344

5445
| Bucket | Purpose |
5546
|--------|---------|
56-
| `volsync-backups` | VolSync PVC backups (Kopia repositories) |
57-
| `postgres-backups` | CNPG and Crunchy database backups |
47+
| `volsync` | VolSync PVC backups (Restic repositories) |
5848

59-
Create them if they don't exist:
49+
Create it if it doesn't exist:
6050
```bash
61-
mc mb truenas/volsync-backups
62-
mc mb truenas/postgres-backups
51+
mc alias set rustfs http://192.168.10.133:30292 <access_key> <secret_key>
52+
mc mb rustfs/volsync
6353
```
54+
55+
## Secret Structure
56+
57+
Each app has an ExternalSecret that creates a Secret with this structure:
58+
59+
```yaml
60+
apiVersion: v1
61+
kind: Secret
62+
metadata:
63+
name: <app>-volsync-secret
64+
type: Opaque
65+
stringData:
66+
RESTIC_REPOSITORY: s3:http://192.168.10.133:30292/volsync/<app>
67+
RESTIC_PASSWORD: <from 1Password rustfs.restic_password>
68+
AWS_ACCESS_KEY_ID: <from 1Password rustfs.access_key>
69+
AWS_SECRET_ACCESS_KEY: <from 1Password rustfs.secret_key>

docs/storage-architecture.md

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,37 @@ graph LR
7474

7575
### PVC Backups (VolSync)
7676

77-
All application PVCs are backed up daily at 2 AM using VolSync with Restic:
77+
Application PVCs are backed up using VolSync with Restic, with a tiered schedule:
78+
79+
**Critical Apps (Hourly):**
80+
home-assistant, paperless-ngx, karakeep, meilisearch, n8n, immich, open-webui, khoj
81+
82+
| Setting | Value |
83+
|---------|-------|
84+
| Schedule | `0 * * * *` (hourly) |
85+
| Retention | 24 hourly + 7 daily |
86+
87+
**Non-Critical Apps (Daily):**
88+
container-registry, redis, mqtt, searxng, fizzy, nginx, jellyfin, nestmtx, homepage-dashboard, plex
7889

7990
| Setting | Value |
8091
|---------|-------|
8192
| Schedule | `0 2 * * *` (daily at 2 AM) |
8293
| Retention | 14 days |
94+
95+
**Common Settings:**
96+
97+
| Setting | Value |
98+
|---------|-------|
8399
| Backend | Restic |
84100
| Target | RustFS S3 on TrueNAS (192.168.10.133:30292) |
85101
| Bucket | `volsync` |
86102
| Copy Method | Snapshot |
87103

88104
Each app has:
89105
- `ReplicationSource` - Defines backup schedule and retention
90-
- `ReplicationDestination` - Pre-provisioned for restore capability
106+
- `ReplicationDestination` - Dormant restore definition (no trigger)
107+
- `PVC` - References ReplicationDestination via `dataSourceRef`
91108
- `ExternalSecret` - Pulls S3 credentials from 1Password
92109

93110
### Database Backups (Native)
@@ -107,31 +124,44 @@ PostgreSQL databases use their native backup tools:
107124

108125
## 3. Disaster Recovery
109126

110-
### Restoring a PVC (VolSync)
111-
112-
When you need to restore a PVC from backup:
127+
### Volume Populator Pattern (Automatic Restore)
113128

114-
1. **Trigger the ReplicationDestination**:
115-
```bash
116-
kubectl patch replicationdestination <app>-restore -n <namespace> \
117-
--type merge \
118-
-p '{"spec":{"trigger":{"manual":"restore-'$(date +%s)'"}}}'
119-
```
129+
PVCs use the **Volume Populator** pattern for automatic restore:
120130

121-
2. **Wait for restore to complete**:
122-
```bash
123-
kubectl get replicationdestination <app>-restore -n <namespace> -w
124-
```
125-
126-
3. **Update PVC to use restored data** (if needed):
127131
```yaml
132+
# In each app's PVC
128133
spec:
129134
dataSourceRef:
130135
kind: ReplicationDestination
131136
apiGroup: volsync.backube
132137
name: <app>-restore
133138
```
134139
140+
**How it works:**
141+
1. PVC references a dormant ReplicationDestination (no trigger)
142+
2. When PVC is newly created (no existing Longhorn volume), Kubernetes uses the dataSourceRef
143+
3. VolSync automatically restores from S3 backup to populate the new PVC
144+
4. If Longhorn already has the data, dataSourceRef is ignored
145+
146+
**This enables zero-intervention restore:**
147+
- Deploy app → PVC created → auto-restore from S3 → app starts with data
148+
- Longhorn replication is Layer 1 (node failure)
149+
- S3 backup is Layer 2 (cluster loss)
150+
151+
### Manual Restore (if needed)
152+
153+
For manual restore scenarios, you can trigger the ReplicationDestination:
154+
155+
```bash
156+
# Add manual trigger to force restore
157+
kubectl patch replicationdestination <app>-restore -n <namespace> \
158+
--type merge \
159+
-p '{"spec":{"trigger":{"manual":"restore-'$(date +%s)'"}}}'
160+
161+
# Wait for restore to complete
162+
kubectl get replicationdestination <app>-restore -n <namespace> -w
163+
```
164+
135165
### Restoring a Database
136166

137167
**CloudNativePG:**
@@ -159,11 +189,11 @@ After a complete cluster rebuild:
159189

160190
| Feature | Before (Longhorn) | Now (VolSync) |
161191
|---------|-------------------|---------------|
162-
| Backup tool | Longhorn built-in | VolSync + Kopia |
163-
| Backup schedule | RecurringJobs (tiered) | Single daily schedule |
164-
| Restore method | Hardcoded restore-job.yaml | Declarative ReplicationDestination |
192+
| Backup tool | Longhorn built-in | VolSync + Restic |
193+
| Backup schedule | RecurringJobs (tiered) | Tiered: hourly (critical) + daily (non-critical) |
194+
| Restore method | Hardcoded restore-job.yaml | Volume Populator (automatic on PVC create) |
165195
| Database backups | PVC snapshots (inconsistent) | Native WAL archiving (consistent) |
166-
| Complexity | Multiple tiers, shell scripts | Simple, uniform config |
196+
| Complexity | Multiple tiers, shell scripts | Declarative YAML per app |
167197

168198
## 5. Monitoring
169199

0 commit comments

Comments
 (0)