modulo 08 / lezione 58

Pubblicare con responsabilità: sicurezza e progetto integrato

Database in produzione: backup, migration, accessi

Preparare la persistenza per un uso reale, dove perdere dati o cambiare schema senza piano è costoso.

75 minVibe Coding

Database in produzione: backup, migration, accessi

In sviluppo, perdere dati è fastidio. In produzione è incidente. La differenza fra prototipo e produzione, per il database, sta in tre cose: backup testati, migrazioni pianificate, accessi controllati. Il modello AI non gestisce nessuna delle tre senza istruzioni esplicite.

Avvertenza: le operazioni descritte (drop colonne, drop tabelle, restore) sono distruttive. Vanno sempre testate su DB di staging prima di produzione. In produzione, fare backup PRIMA di ogni operazione di schema, non dopo.

Perché questa lezione conta

Backup è inutile se non testato (scoprire al disastro che il restore non funziona = doppio disastro). Migrazione mal fatta perde dati o causa downtime. Accessi senza politica = chiunque cambia schema in produzione. Tre aree che il vibe coder ignora finché non scoppia. Imparare prima del primo deploy serio risparmia incidenti.

Obiettivo operativo

Alla fine devi saper:

  1. impostare backup automatici e testarne il restore;
  2. scrivere migrazioni reversibili senza perdere dati;
  3. configurare accessi minimi per ogni ambiente.

Nucleo della lezione

1. Backup

Frequenza: dipende da quanto perderesti. Per app commerciale: backup ogni 1-6 ore. Per app personale: giornaliero. Mai meno di settimanale per dati che non possono essere ricostruiti.

Tipi:

  • Full: copia completa. Costoso ma autocontenuto.
  • Incrementale: solo cambi dall’ultimo full. Veloce, richiede full + tutti gli incrementali per restore.
  • Point-in-time recovery (PITR): ricostruisci stato a un timestamp arbitrario. Postgres con WAL archiving, MySQL con binlog. Più sofisticato.

Storage: locale + offsite. Backup nello stesso datacenter del DB = single point of failure. Cloud storage separato (S3, R2) o region diverso.

Test del restore: il backup non testato è ipotesi, non garanzia. Esegui restore mensile in ambiente staging. Se il restore fallisce, lo scopri prima del bisogno.

Retention: quanto tempo tenere ogni backup. Esempio: ultimi 7 giornalieri + ultimi 4 settimanali + ultimi 12 mensili. Politica esplicita.

Provider managed: la maggior parte dei DB managed (Supabase, Neon, Turso, AWS RDS, GCP Cloud SQL) offre backup automatici. Verifica: frequenza, retention, test del restore documentato.

2. Migrazioni

Migrazione: cambio di schema (aggiungere colonna, modificare tipo, cambiare vincolo) versionato e applicabile in modo riproducibile.

Tool: Drizzle migrations, Prisma migrations, Alembic (Python), golang-migrate, Atlas, etc. Mai modifiche manuali al DB di produzione.

Caratteristiche di buone migrazioni:

  • Reversibili: ogni migrazione ha up (apply) e down (rollback). Testato.
  • Idempotenti: applicabili più volte senza side effect. IF NOT EXISTS, IF EXISTS.
  • Atomiche: una migrazione = una modifica logica. Non mescolare 5 cose.
  • Compatibili durante deploy: vecchio codice deve poter girare con nuovo schema (e viceversa) durante rolling deploy.

Pattern per cambi rischiosi (rinomina colonna):

  1. Aggiungi nuova colonna (vuota).
  2. Backfill: popola nuova da vecchia.
  3. Deploy app che scrive su entrambe e legge da nuova.
  4. Verifica.
  5. Migrazione che rimuove vecchia colonna.

Tre o quattro deploy invece di uno. Lento ma sicuro. Per cambi non rischiosi (aggiungi colonna nullable), un deploy basta.

Test: prima di applicare in produzione, applica su staging con copia recente di prod. Se rompe staging, rompe prod.

Backup pre-migration: sempre. Non importa quanto sembri innocua.

3. Accessi e ambienti

Separazione ambienti:

  • Sviluppo locale: ogni dev ha il suo DB locale (Docker, SQLite, Postgres locale). Dati seed, no PII reale.
  • Staging: copia di prod (con dati anonimizzati o seed realistico). Testa migrazioni qui.
  • Produzione: solo accessibile a operatori designati. Mai dal laptop dello sviluppatore per default.

Credenziali:

  • ogni ambiente ha credenziali separate;
  • credenziali con privilegi minimi necessari (l’app non ha bisogno di DROP TABLE);
  • accesso umano con account personali, non shared;
  • audit log su accessi privilegiati.

Connessioni sicure:

  • TLS sempre (no plaintext);
  • IP allowlisting o VPC peering se possibile;
  • niente DB esposto su internet pubblico.

Privilegi tipici:

  • ruolo app: SELECT, INSERT, UPDATE, DELETE su tabelle dell’app. NIENTE DDL.
  • ruolo migrazione: + DDL (CREATE/ALTER/DROP). Usato solo durante migrazioni.
  • ruolo admin: tutto. Solo per emergenze, audit log obbligatorio.

Procedura pratica

Per andare in produzione con un DB:

  1. Backup automatico: configura. Verifica frequenza accettabile.
  2. Test restore: una volta, prima del primo deploy. Documenta procedura.
  3. Migrazioni versionate: tool integrato, file in repo.
  4. Staging: ambiente di test con copia di prod.
  5. Credenziali: separate per dev/staging/prod. Mai stesso .env.
  6. Privilegi minimi: app non ha DDL.
  7. Monitoring: connessioni, query lente, errori, dimensione DB.
  8. Procedura di rollback: documentata, testata almeno una volta.

Laboratorio guidato

Setup minimo per piccola app:

Stack: Postgres su Supabase, app deploy su Vercel.

Backup: Supabase fa backup automatici giornalieri (free tier 7 giorni retention). Per maggiore frequenza/retention, upgrade.

Test restore: una volta, scarica backup, restore in DB di test, verifica integrità (SELECT count(*) FROM critical_table).

Migrazioni: Drizzle con drizzle-kit generate + drizzle-kit migrate. File drizzle/ versionati in repo. Pipeline CI applica migrazioni a staging prima del deploy app.

Pattern di rinomina (esempio emailemail_address):

Migration 1 (additiva):
ALTER TABLE users ADD COLUMN email_address VARCHAR(254);
UPDATE users SET email_address = email;
CREATE INDEX idx_users_email_address ON users(email_address);

Migration 2 (codice aggiornato):
-- nessun cambio DB. Solo deploy app che scrive su entrambe, legge da email_address.

Migration 3 (cleanup, dopo che il vecchio codice non è più in giro):
ALTER TABLE users DROP COLUMN email;

Tre deploy. Sicuri.

Accessi:

  • dev locale: docker postgres, dati seed.
  • staging: Supabase staging project, credenziali separate.
  • prod: Supabase prod project, credenziali in pannello Vercel, mai locale.

Doc in docs/database.md: procedura backup, restore, migration, rollback.

Output atteso

Documento docs/database.md per il tuo progetto:

  • backup: frequenza, retention, location, comando di restore.
  • migrations: tool, dove vivono, come applicarle.
  • ambienti: dev/staging/prod, credenziali separate.
  • procedure di emergenza: restore, rollback, escalation.

Studio passo passo

Studia questa lezione in tre passaggi, senza correre subito al prompt o al codice.

  1. Prima lettura: chiarisci l’obiettivo: preparare la persistenza per un uso reale, dove perdere dati o cambiare schema senza piano è costoso. Se non riesci a riscriverlo in una frase tua, rileggi il nucleo della lezione.
  2. Seconda lettura: trasforma i contenuti in domande operative:
  • Backup, restore testato, ambienti separati, permessi minimi, connessioni sicure e log accessi.
  • Migrazioni: cambiare schema senza distruggere dati, prevedere rollback e dati legacy.
  • Seed e dati demo: separare ciò che serve a sviluppo da ciò che vive in produzione.
  1. Applicazione: svolgi il laboratorio: disegnare un piano minimo per backup, migrazione e accesso di una app con utenti e contenuti. L’output da ottenere è: una checklist database production-ready prima del primo deploy pubblico.

Prima di passare alla lezione successiva, controlla di avere un artefatto concreto: una tabella, un prompt, una checklist, un mini report, un diff commentato o una decisione scritta. Nel vibe coding la comprensione resta astratta finché non produce una traccia verificabile.

Checklist di verifica

  • backup automatico configurato per il mio progetto;
  • ho testato un restore almeno una volta;
  • migrazioni versionate e applicate via tool;
  • ambiente staging esiste;
  • credenziali separate per dev/staging/prod;
  • l’app ha privilegi minimi (no DDL);
  • documentazione operativa scritta.

Errori comuni

Niente backup. Disco perso = lavoro perso. Quasi sempre il primo provider managed lo offre default; verificalo.

Backup mai testato. Scoperta al disastro che il file è corrotto/incompleto. Test mensile.

Modifiche manuali in produzione. “Aggiungo questa colonna a mano”. Schema diverge da repo. Bug futuri inspiegabili.

Stesso DB per dev e prod. Test di sviluppo cancella dati di produzione: già successo.

Credenziali condivise. Stesso utente DB per tutti. Audit impossibile.

App con DROP TABLE privilege. SQL injection diventa DROP TABLE. Privilegi minimi.

Migrazione gigante. 1000 righe di SQL in un colpo. Errore in mezzo, stato incoerente. Migrazione atomica per cambio.

Niente rollback testato. “Funziona”. Quando rompe, non sai tornare indietro.

Prompt di lavoro

Aiutami a impostare strategy database per produzione.

Stack: [DB engine + provider]
App scala stimata: [utenti, volume dati]
Frequenza modifiche schema: [bassa/media/alta]
Criticità dati: [poco / molto]

Voglio:

1. Backup: frequenza, retention, location consigliate. Comando esempio per restore manuale.

2. Migrations: tool consigliato per il mio stack, struttura file, integrazione con CI.

3. Pattern per cambi rischiosi (rinomina colonna, drop colonna usata): sequenza di deploy multi-fase.

4. Ambienti: dev/staging/prod separation, naming, credenziali.

5. Privilegi: ruoli DB con privilegi minimi per app vs migration vs admin.

6. Monitoring: 5 metriche chiave da osservare.

7. Procedure di emergenza: restore parziale, rollback migration, accesso emergenza.

Output: piano operativo + comandi esempio + checklist setup iniziale.

NON deploy ancora. Voglio prima validare la strategia.

Esercizio finale

Per il tuo progetto attivo: rispondi onestamente alle 5 domande:

  1. Quando è stato l’ultimo backup?
  2. Sai come fare il restore?
  3. L’hai mai testato?
  4. Le tue credenziali di produzione sono separate da sviluppo?
  5. Esiste rollback documentato per le ultime 3 migrazioni?

Quasi sempre 2-3 risposte sono “no” o “non sono sicuro”. Quei “no” sono incidenti pronti a succedere. Sistema prima del prossimo deploy.