Salta ai contenuti
Sirio è in beta privata: sorgenti e installer vengono inviati via email a chi la prova. Chiedi di partecipare.

Backup

Sirio salva ogni sito con restic: i suoi volumi Docker, le cartelle dell’host montate dai suoi container e i suoi database, esportati con i loro strumenti. Gli snapshot sono cifrati con una password che hai solo tu, deduplicati (un backup notturno salva solo ciò che è cambiato) e sfoltiti secondo la politica di conservazione che scegli.

restic gira come container usa-e-getta, avviato da Sirio tramite il socket di Docker: non serve nessun helper privilegiato né alcuna eccezione alla sandbox del servizio, e Sirio stesso non legge mai i dati. L’immagine è fissata per digest (SIRIO_RESTIC_IMAGE la sostituisce).

Gli snapshot sono normali snapshot restic. Tutto ciò che fa Sirio si può verificare o annullare con il solo restic, da qualunque macchina, anche se il server e Sirio non ci sono più: vedi Kit di recupero.

Una destinazione è un repository restic. Più piani, e più siti, possono condividerla.

Tipo Repository Credenziali
Cartella locale un percorso su questo server nessuna
SFTP sftp:utente@host:/percorso una chiave SSH, generata da Sirio o incollata
Amazon S3 s3:s3.<regione>.amazonaws.com/<bucket>/<cartella> access key e secret key
Compatibile S3 s3:<endpoint>/<bucket>/<cartella> access key e secret key
Backblaze B2 s3:https://s3.<regione>.backblazeb2.com/<bucket>/<cartella> key ID e application key
Google Cloud Storage gs:<bucket>:/<cartella> la chiave JSON di un service account
  • Cartella locale. Se manca la crea Docker. Sullo stesso disco dei dati protegge dagli errori, non da un guasto del disco: usa un secondo disco, un NAS montato, o anche un’altra destinazione.
  • SFTP. Sirio si collega con una sua chiave e solo alla chiave host che hai confermato: quando crei la destinazione, Sirio legge la chiave del server e ne mostra l’impronta, che confronti con quella del server stesso (ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub). Un server che più avanti presenta un’altra chiave viene rifiutato, mai accettato alla cieca: i backup verso di lui falliscono prima di esportare o fermare qualunque cosa, e l’esecuzione lo dice. Se il server è stato reinstallato, modifica la destinazione e conferma la sua nuova impronta. Se la chiave la genera Sirio, aggiungi la chiave pubblica che mostra a ~/.ssh/authorized_keys dell’utente sul server. Evita backup come nome utente sui server Debian e derivati: lì è un account di sistema, con una home diversa da quella dove metteresti la chiave.
  • Compatibile S3. MinIO, Wasabi, Cloudflare R2, Hetzner, Scaleway, OVH e simili: indica l’endpoint come lo documenta il tuo provider, e la regione se la richiede.
  • Backblaze B2 passa dall’API compatibile S3 di B2, che la documentazione di restic consiglia rispetto al backend nativo b2. L’endpoint è nei dettagli del bucket (s3.<regione>.backblazeb2.com).
  • Google Cloud Storage. Il service account ha bisogno di Storage Object Admin sul bucket. L’ID progetto, se lasciato vuoto, viene preso dalla chiave.

Dai a ogni destinazione credenziali limitate al suo bucket. Sono salvate cifrate con la chiave segreta di Sirio, come i token Git, e l’API non le restituisce mai: modificando una destinazione, un campo credenziale lasciato vuoto mantiene quello salvato.

Ogni snapshot è cifrato con la password del repository. Quando crei una destinazione Sirio ne genera una e la mostra una volta sola: salvala fuori dal server, in un password manager. Senza di lei nessuno può leggere i backup — Sirio non può recuperarla per te, e se il server va perso, la copia nel database di Sirio va persa con lui.

Per usare un repository che esiste già (creato a mano, o da un altro Sirio), scegli invece Usa la password di un repository restic esistente.

Verifica apre il repository con la sua password e lo crea se non esiste ancora — su storage compatibile S3, B2 e GCS anche il bucket, se la chiave può crearne uno. Il primo backup fa lo stesso da solo. restic ripete una richiesta che fallisce per circa quindici minuti, il che aiuta un backup a superare un’interruzione di rete; le verifiche, gli elenchi degli snapshot e l’inizio di ogni esecuzione invece si arrendono dopo tre tentativi e riportano l’errore di restic, così le credenziali sbagliate emergono in pochi secondi.

Un piano salva un sito in una destinazione, secondo una pianificazione, conservando ciò che dice la politica di conservazione.

I container assegnati al sito (da Container, o rivendicati dal deploy di una pipeline collegata al sito). Per ognuno il piano decide come:

Modalità Cosa succede
Dump del database il database viene esportato con il suo strumento mentre gira. Coerente, e i suoi file di dati restano fuori. La scelta predefinita per un database riconosciuto.
Ferma durante la copia il container viene fermato mentre se ne copiano i file, poi riavviato. Coerente, con un breve fermo.
Copia a caldo i file vengono copiati mentre il container gira. La scelta predefinita per tutto il resto: va bene per upload e file statici, non per i file di un database.
Escludi di questo container non si salva nulla.

Cosa si copia: i volumi Docker (con nome e anonimi) e le cartelle dell’host montate in bind. Mai: il socket di Docker, i percorsi di sistema dell’host (/proc, /sys, /dev, /run, /etc/hosts e simili), i mount tmpfs. Un volume condiviso da due container si copia una volta.

Ogni volume e cartella dell’host si può escludere singolarmente: basta togliere la spunta nella tabella dei container del piano. La scelta è del piano, non del container, perché un volume condiviso da due container si copia una volta sola: escluderlo da uno lo esclude da entrambi. Una cartella esclusa che sta dentro una cartella copiata (ad esempio /srv/shop/media/thumbs sotto /srv/shop/media) viene saltata da restic. Un container in modalità Ferma durante la copia con tutti i mount esclusi non viene fermato.

Un database in modalità dump che non è in esecuzione non si può esportare: i suoi file sono fermi, quindi vengono copiati, il che è sicuro.

Sirio riconosce le immagini ufficiali (e quelle Bitnami) di MySQL, MariaDB, Percona e PostgreSQL (con PostGIS, TimescaleDB, pgvector) dal nome dell’immagine: le applicazioni che si collegano a un database ne portano anche le variabili, quindi l’ambiente da solo trarrebbe in inganno.

Il dump gira dentro il container del database (docker exec), con uno script fisso che legge le credenziali dall’ambiente del container stesso — le variabili con cui hai configurato l’immagine. Nessuna password passa da Sirio, e nessuna finisce su una riga di comando.

  • MySQL / MariaDB: come root quando sono impostate MYSQL_ROOT_PASSWORD / MARIADB_ROOT_PASSWORD (o le varianti _FILE, o quelle per la password vuota), tutto con --all-databases; altrimenti come MYSQL_USER solo su MYSQL_DATABASE. mariadb-dump quando c’è (MariaDB 11 non ha più mysqldump). L’editor del piano avvisa quando non trova credenziali.
  • PostgreSQL: pg_dumpall --clean --if-exists come POSTGRES_USER (predefinito postgres), ruoli compresi: il dump cancella ogni database prima di ricrearlo, così si ripristina su un cluster in funzione.

Il dump viene scritto in una cartella temporanea sotto SIRIO_DATA_DIR/backups, incluso nello snapshot e cancellato subito dopo: serve lì tanto spazio libero quanto è grande il dump. Un dump fallito non lascia file, così un dump troncato non sembra mai buono; l’esecuzione risulta fallita, ma il resto del sito viene salvato comunque.

Ogni ora a un minuto, ogni giorno o ogni settimana a un’ora, oppure un’espressione cron (cinque campi, più @hourly, @daily, @weekly…), nel fuso orario del server. Un backup saltato mentre Sirio era fermo parte una volta alla ripartenza. Un piano può anche essere eseguito solo a mano.

Un backup e un deploy dello stesso sito non si sovrappongono mai: chi parte per secondo aspetta, e il suo log lo dice. I backup girano uno alla volta.

Una pipeline collegata a un sito può salvarlo come uno dei suoi step: aggiungi uno step Backup, scegli uno dei piani del sito e mettilo prima degli step di deploy. Lo step aspetta lo snapshot (il suo timeout limita anche il backup) e fa fallire l’esecuzione se il backup fallisce, così un deploy non va mai avanti senza la sua rete di sicurezza. Il backup compare nello storico del piano come gli altri, avviato da “pipeline”.

Dopo ogni backup, forget --prune di restic rimuove gli snapshot di questo piano oltre i numeri che hai impostato — gli ultimi N, uno al giorno per N giorni, uno a settimana, uno al mese — e ne libera lo spazio. Con tutti i numeri a zero non si rimuove mai nulla.

La conservazione tocca solo gli snapshot del piano (tag plan:<id>, fatti da questo host), quindi piani che condividono una destinazione non si sfoltiscono a vicenda.

Kit di recupero (in Destinazioni, dopo aver confermato la tua password) mostra il necessario per raggiungere i backup con il solo restic: il repository, la sua password, le variabili che nominano le credenziali dello storage (quelle restano tue da inserire) e i comandi per elencare e ripristinare.

Finestra del terminale
export RESTIC_REPOSITORY='s3:https://s3.eu-central-003.backblazeb2.com/my-backups/sirio'
export RESTIC_PASSWORD='…'
export AWS_ACCESS_KEY_ID='…'
export AWS_SECRET_ACCESS_KEY='…'
restic snapshots --tag site:shop
restic restore latest --host web1 --tag site:shop --target ./restore

Dentro uno snapshot, backup/<sito>/ contiene volumes/<volume> (volumi Docker), binds/<percorso sull'host> (cartelle dell’host) e databases/<container>.sql (dump). Per ripristinare un database, passa il dump al suo client: mysql < shop-db.sql oppure psql -f shop-db.sql.

Ogni snapshot porta i tag sirio, site:<sito> e plan:<id del piano>, e il nome host del server.

La pagina di un piano (il suo nome in Backup) elenca i suoi snapshot — solo i suoi, anche quando la destinazione è condivisa — e permette di sfogliarli cartella per cartella. Da lì:

  • Scarica qualunque file così com’è, o qualunque cartella come .zip, letti direttamente dal repository.
  • Ripristina un volume: al posto del volume del sito, o in uno nuovo (i dati attuali restano intatti; monta il nuovo volume dove ti serve). La sostituzione ferma i container che usano il volume, ne rende il contenuto esattamente quello dello snapshot — i file aggiunti dopo vengono cancellati — e li riavvia.
  • Ripristina una cartella dell’host, solo al suo posto, tra le cartelle che i container del sito montano ancora: stesso fermo, sostituzione, riavvio.
  • Ripristina un database dal suo dump in uno dei container database del sito in esecuzione. Di norma gli altri container del sito vengono fermati nel frattempo, così nessuna applicazione scrive a metà e PostgreSQL può cancellare i database che ricrea. MySQL/MariaDB si fermano al primo errore; per PostgreSQL, i due errori sul ruolo con cui gira il ripristino sono attesi, qualunque altro fa fallire il ripristino. I dump fatti prima che Sirio aggiungesse --clean si ripristinano correttamente solo in un database vuoto.

I ripristini girano nella stessa coda dei backup, aspettano qualunque backup o deploy del sito e hanno una pagina con il log in diretta. Ogni destinazione del ripristino viene controllata due volte, alla richiesta e all’avvio: un ripristino può scrivere solo in ciò che appartiene al sito del piano, mai altrove sull’host.

  • Backup (permesso globale): le destinazioni, e i piani di ogni sito. Le sue eccezioni valgono ovunque, come per gli altri permessi globali.
  • Su un sito: Backup (vedere piani, esecuzioni e snapshot del sito, e i nomi che contengono), Modifica (creare, modificare ed eliminare i suoi piani, scegliendo tra le destinazioni esistenti), Esecuzione (avviare e interrompere un backup a mano) e Ripristino e download (rileggere i dati salvati: scaricare file, ripristinarli al posto di quelli del sito). Il ripristino è un’azione a sé perché può sostituire dati in uso.

Chi ha solo permessi di sito vede i nomi delle destinazioni, non dove si trovano.

  • Log delle esecuzioni: SIRIO_DATA_DIR/backups/logs, conservati per le ultime SIRIO_RUN_RETENTION esecuzioni di ogni piano.
  • La cache di restic: il volume Docker sirio-restic-cache, così un’esecuzione non riscarica gli indici del repository.
  • Durante un’esecuzione: i dump sotto backups/staging, i file con le credenziali sotto backups/tmp (0600, montati in sola lettura nel container di restic, cancellati alla fine).

Un riavvio di Sirio a metà di un backup o di un ripristino lo segna come fallito, rimuove il container restic rimasto e riavvia i container che aveva fermato.