Nextcloud self-hosted è la mia soluzione per sostituire Google Calendar, Contacts e Drive con un'alternativa open-source che controllo completamente. Deploy su Oracle Cloud Infrastructure usando il free tier (4 OCPU ARM, 24GB RAM - gratis per sempre).
Il problema: La prima versione funzionava, ma era fragile. Setup manuale con 50+ comandi, 1GB RAM che crashava, e soprattutto: zero garanzie che in caso di disaster potessi recuperare tutto.
La soluzione: Riscrivere l'intera infrastruttura con Infrastructure as Code (Terraform), aggiungere monitoring production-grade, implementare dual backup strategy, e testare ripetutamente il disaster recovery finché non potessi dire con certezza: "Posso distruggere tutto e ricostruirlo in 10 minuti".
Questo articolo racconta il percorso da "pet server" curato manualmente a "cattle infrastructure" automatizzata, le decisioni architetturali chiave, le sfide affrontate, e cosa ho imparato nel processo.
Nell' articolo di qualche giorno fa, vi avevo raccontato la mia prima esperienza con Nextcloud self-hosted. Era passata solo una settimana dal Linux Day e, piena di entusiasmo (e forse incoscienza), avevo deployato Nextcloud AIO su Oracle Cloud.
Spoiler: è stato un piccolo disastro.
Container che crashavano, sincronizzazioni sovrapposte dai vari dispositivi...notti passate a debuggare, e alla fine una soluzione minimale con solo 2 container per sopravvivere nei limiti di 1GB di RAM.
Ma funzionava. E per un paio di settimane è stata la mia soluzione.
---
🎯 Il Problema: Quando "Funziona" Non Basta
Dopo alcuni giorni di utilizzo quotidiano, ho iniziato a realizzare i limiti di quella soluzione "fatta a mano":
I Nodi Dolenti
1. Zero Disaster Recovery
Cosa succede se cancello l'istanza per sbaglio?
Come recupero i dati? Quanto tempo serve?
Spoiler: non lo sapevo. E questo mi terrorizzava.
2. Backup Artigianali
Script bash scritti di fretta
Path hardcoded ovunque
"Funziona sul mio PC"
3. Configurazione Manuale
Non so quante azioni manuali da eseguire
4. Scalabilità Zero
1GB RAM = no monitoring, no extras
Impossibile aggiungere Grafana/Prometheus
"Se voglio aggiornare devo pregare"
Mi sono resa conto: avevo sostituito Google Calendar, ma avevo creato un "pet server" fragile che richiedeva cure manuali continue.
---
🏗️ La Visione: Infrastructure as Code
Volevo qualcosa di diverso. Non solo "far funzionare Nextcloud", ma costruire un'infrastruttura che fosse:
✅ Riproducibile: `terraform apply` e in 10 minuti è online
✅ Resiliente: posso distruggere e ricreare senza perdere dati
✅ Documentata: il codice È la documentazione
✅ Scalabile: aggiungere monitoring non deve far crashare tutto
✅ Testabile: voglio SAPERE che il disaster recovery funziona
In pratica: passare da "pet server" a "cattle infrastructure".
---
🧠 Decisioni Architetturali Chiave
1. Terraform vs Ansible vs Manuale
La mia scelta: Terraform
Perché non manuale?
50 comandi da ricordare? No grazie.
Perché non Ansible?
Ansible è imperativo: descrive "passi" da fare
Terraform è dichiarativo: descrive lo "stato finale"
Con Terraform: state drift detection automatico
(Momento super sincerità) Non ho ancora esplorato a fondo Ansible
Momento decisivo:
Quando ho scoperto che posso fare `terraform destroy` seguito da `terraform apply` e avere indietro l'intera infrastruttura in 10 minuti, ho capito che era la strada giusta.
2. Il Pattern "Pets vs Cattle"
Questo è stato il game changer mentale.
Prima (Pets):
┌─────────────────────┐
│ Istanza Unica │ ← Se muore, panico totale
│ - OS │
│ - Nextcloud │
│ - TUTTI I DATI │ ← Accoppiamento pericoloso
└─────────────────────┘
Dopo (Cattle + Pet):
┌─────────────────────┐
│ Istanza Compute │ ← Cattle: ricreabile in10 min
│ - OS │
│ - Nextcloud │
└────────┬────────────┘
│ mount
↓
┌─────────────────────┐
│ Volume Persistente │ ← Pet: protetto, mai distrutto
│ - Dati utente │ prevent_destroy = true
│ - Database │
│ - Backup Borg │
└─────────────────────┘Code language:JavaScript(javascript)
La rivelazione: separare ciò che è ricreabile (compute) da ciò che deve sopravvivere (dati). Sembra ovvio, ma cambia tutto.
3. Monitoring Stack: Da Lusso a Necessità
Setup precedente: 1GB RAM, no monitoring, "speriamo funzioni"
Setup attuale: 24GB RAM gratuiti (ARM A1.Flex)
Prometheus: metriche sistema + container
Grafana: dashboard visuale
Node Exporter: CPU, RAM, disk, network
cAdvisor: metriche Docker real-time
Il valore: non più "è caduto tutto, aiuto!", ma "alert 2h prima che il disco si riempia".
---
🛠️ L'Implementazione: Le Fasi
Fase 1: Infrastructure as Code (Terraform)
Ho tradotto tutto il setup manuale in ~500 righe di Terraform:
Risultato: `terraform apply` e dopo ~8 minuti ho Nextcloud + monitoring funzionante, SSL incluso.
Fase 2: Backup Strategy Duale
Ho imparato che servono DUE tipi di backup:
1. Borg Backup (System-level)
Location: /mnt/nextcloud-data/borg-backups/ # Sul volume persistente!
Schedule: Daily 04:00 UTC
Retention: 7 giorni
Encryption: YesCode language:HTTP(http)
2. Export Leggibile (Data portability)
Location: ~/nextcloud-exports/ (PC locale)
Schedule: Weekly
Formato: .ics (calendari), .vcf (contatti)
Scopo: Import in altri dispositivi se serveCode language:HTTP(http)
Fase 2.5: Il Superpotere degli Script Shell 🚀
E qui arriva la parte che mi ha fatto innamorare di questo progetto: lo script `local-backup-sync.sh`.
Non è solo "uno script di backup". È un esempio perfetto di quanto potere ci sia in poche centinaia di righe di Bash.
Il problema che risolve:
Borg backups sono encrypted sul server OCI
Come li sincronizzo sul mio PC senza sbattermi?
Come verifico l'integrità senza fare tutto a mano?
Come estraggo i file quando serve?
La magia dello script:
# Uso interattivo - ti guida passo passo
./local-backup-sync.sh
# Automazione completa - perfetto per cron
./local-backup-sync.sh --sync-only
# Solo estrazione ultimo backup
./local-backup-sync.sh --extract-onlyCode language:PHP(php)
Cosa fa in automatico*(e qui mi stupisco ogni volta):
1. rsync incrementale intelligente
# Solo le differenze, non riscarica tutto!
rsync -avzh --delete \
-e "ssh -i ~/.ssh/key" \
server:/mnt/nextcloud-data/borg-backups/ \
~/nextcloud-backups/Code language:PHP(php)
2. Verifica integrità automatica
# Controlla che i backup non siano corrotti
borg check ~/nextcloud-backups/Code language:PHP(php)
3. Lista backup con metadati
# Mostra tutti i backup disponibili con date, dimensioni, stats
borg list ~/nextcloud-backups/Code language:PHP(php)
4. Statistiche del repository
# Quanto spazio risparmio con deduplica? Quanto è compresso?
borg info ~/nextcloud-backups/Code language:PHP(php)
5. Estrazione interattiva intelligente
Identifica automaticamente il backup più recente
Chiede conferma prima di sovrascrivere
Sistema i permessi automaticamente (`chown`)
Gestisce directory esistenti
6. Logging completo
Ogni operazione loggata
Timestamp, exit codes, errori
Output colorato per scannerizzazione veloce
Ma la cosa più bella? Una volta configurato con cron poi te ne dimentichi. Ogni domenica alle 22:00, silenziosamente:
Sincronizza i backup dal server
Verifica l'integrità
Logga tutto
Se qualcosa va storto, lo trovi nel log
Perché mi entusiasma così tanto?
Perché è l'essenza del buon scripting:
✅ DRY: scritto una volta, usato ovunque
✅ Idempotente: posso eseguirlo 100 volte, fa sempre la cosa giusta
✅ Self-documenting: le opzioni `--help` spiegano tutto
✅ Fail-safe: controlla errori, non rompe nulla
✅ Automatable: perfetto per cron, ma anche usabile manualmente
Il potere degli script shell è proprio questo: prendere operazioni complesse, ripetitive e prone-to-error, e renderle:
Automatiche
Affidabili
Documentate nel codice stesso
Riproducibili
E quando funziona così bene che te ne dimentichi? Quella è la vera automazione. 🎯
Fase 3: Disaster Recovery Testing
Qui è dove molti progetti "production" falliscono: testare veramente il disaster recovery.
Il test:
terraform state pull > before.json
borg list /mnt/nextcloud-data/borg-backups/
# 2. DISTRUGGI TUTTO (solo compute, non volume)
terraform destroy -target=oci_core_instance.nextcloud
# 3. Ricrea da zero
terraform apply
# 4. Verifica dati intatti# Login Nextcloud → Tutti i file presenti ✅# Calendari sincronizzati ✅# Backup Borg ancora lì ✅Code language:PHP(php)
Risultati dopo 3 test completi:
✅ Recovery time: ~10 minuti
✅ Data loss: 0 byte
✅ Confidence level: 100%
Lezione fondamentale: Se non l'hai testato, non funziona.
---
Convincermi a "Distruggere Tutto"
Problema emotivo:
Fare `terraform destroy` sulla mia produzione attiva mi terrorizzava.
**La paura**:
"E se i backup sono corrotti?"
"E se dimentico qualcosa?"
"E se ho hardcoded qualcosa che non ricordo?"
La soluzione:
Primo test su istanza separata
Backup offline sul PC prima di destroy
Screenshot di tutto
YOLO(You Only Live Once!) e destroy 🚀
Risultato:
Dopo il primo test riuscito, ho fatto altri 2 cicli per validare.
Ora dormo tranquilla sapendo di poter ricostruire tutto in 10 minuti.
---
📊 Prima vs Dopo: I Numeri
Metrica
Setup Iniziale
Setup Attuale
Deployment Time
~2 ore manuali
10 minuti automatici
RAM Disponibile
1GB (cramming)
24GB (comfortable)
Monitoring
❌ Niente
✅ Prometheus + Grafana
Disaster Recovery
❌ "Speriamo bene"
✅ Testato 3 volte
Backup Automation
⚠️ Script fragili
✅ Dual strategy + integrity checks
Documentation
⚠️ Sparsa
✅ Codice IS documentazione
Confidence Level
😰 Ansia costante
😎 Tranquillità
Infrastructure Cost
$0/mese
$0/mese (yay free tier!)
---
📌 Quick note sul pattern "Pets vs Cattle":
Pets 🐶: Server trattati come animali domestici (nomi, cure manuali, se muoiono → panico)
Cattle 🐄: Server trattati come bestiame (numerati, automatizzati, se muoiono → rimpiazzati automaticamente)
Il trick: separare ciò che è ricreabile (compute = cattle) da ciò che deve sopravvivere (dati = pet protetto).
💭 Riflessioni: Cosa Ho Imparato
1. Infrastructure as Code Non è "Nice to Have"
Prima pensavo: "IaC serve solo per le grandi aziende"
Ora so: Anche per un progetto personale, la capacità di distruggere e ricreare l'infrastruttura in minuti vale ogni riga di Terraform scritta.
2. "Pets vs Cattle" è un Mindset, Non una Tecnica
Il vero cambio mentale è stato separare:
Ciò che posso permettermi di perdere (compute)
Ciò che non posso perdere MAI (dati)
Una volta capito questo, le decisioni architetturali diventano ovvie.
3. Testare il Disaster Recovery è Come l'Assicurazione
Sembra una perdita di tempo finché non ne hai bisogno. Poi capisci che è l'unica cosa che conta.
4. Gli Script Shell Sono Superpotenze Sottovalutate
Per automazione di sistema, pochi tool battono uno script shell ben scritto:
Zero dipendenze (bash è ovunque)
Perfetto per orchestrare altri tool (rsync, borg, ssh)
Facile da debuggare (esegui riga per riga)
Immediato da modificare (niente compilazione)
Il vero potere: prendere task complessi e renderli "fire and forget".
5. La Documentazione è un Debito Continuo
Non basta scriverla una volta. Deve evolvere col codice.
6. Il Fallimento Iniziale Era Necessario
Senza l'esperienza del primo setup "fatto a mano" con 1GB RAM e crash continui, non avrei apprezzato il valore di un'architettura ben pensata.
A volte devi toccare il ferro caldo per imparare.
---
🔮 Next Steps: Cosa Manca
Nonostante i progressi, ci sono ancora aree da migliorare:
1. Alerting Automatico
Status: ⚠️ Monitoring passivo
Goal: Alertmanager + notifiche Telegram
Alert se CPU > 80% per 5 minuti
Alert se disco > 85%
Alert se backup fallisce
2. Off-site Backup su Object Storage
Status: ⚠️ Backup solo su volume OCI
Goal: Sync automatico su OCI Object Storage
10GB free tier disponibile
Vera separazione geografica
Protection contro delete accidentale volume
3. CI/CD Pipeline Testing
Status: ✅ GitHub Actions per validation
Goal Futuro: Test automatici disaster recovery
Nightly deploy su istanza test
Restore backup + verifica integrità
Report automatico
---
🎯 Conclusioni: Il Viaggio Continua
Due settimane fa scrivevo:
> "Self-hosting is hard. But it's worth it."
Oggi aggiungo:
> "Infrastructure as Code makes self-hosting sustainable."
Non basta far funzionare qualcosa. Serve costruire sistemi che:
Sopravvivono al tempo
Sopravvivono agli errori umani
Sopravvivono alla tua memoria a breve termine
Questo progetto mi ha insegnato che l'obiettivo non è "deployare Nextcloud", ma costruire un sistema resiliente che possa evolvere, rompersi, e auto-ripararsi.
E soprattutto: che posso distruggere e ricostruire in 10 minuti mentre bevo un caffè. ☕
P.S. Se state considerando di fare self-hosting, il mio consiglio è: iniziate semplice (come ho fatto io), rompete tutto (come ho fatto io), e poi ricostruite bene (come sto facendo ora).
• Sviluppo del sito web di Averna Spazio Open utilizzando WordPress, con Oxygen Builder per un design personalizzato e Advanced Custom Fields (ACF) per la gestione dinamica del contenuto. • Creato un sistema di invio di idee degli utenti, che venivano pubblicate sul sito, con una funzione di voto per selezionare l’idea migliore annualmente. • […]
Introduzione al Progetto NutriCHOice rappresenta un'innovativa soluzione nell'ambito della nutrizione personalizzata, sviluppata come progetto finale del Bootcamp AI di Edgemony. Il sistema utilizza un approccio "Generate then Fix" (Genera e Correggi) per creare ricette personalizzate che rispettano specifici obiettivi nutrizionali, con particolare attenzione al contenuto di carboidrati (CHO). Evoluzione del Progetto: Da RAG a "Generate […]