Preparazione al ripristino
Libre WebUI fornisce un inventario di ripristino in sola lettura come primo controllo di sicurezza per backup e ripristino. Segnala quale stato noto esiste e quali condizioni rilevate impediscono un'istantanea. Non acquisisce un blocco di manutenzione e non copia, cifra, carica, elimina, ripara o ripristina dati.
libre-webui recovery-check --json > recovery-inventory.json
Da un checkout dei sorgenti, esegui una volta npm run build:backend e sostituisci
libre-webui recovery-check con npm run recovery:check --. Le installazioni npx e
Homebrew incluse esaminano ~/.libre-webui per impostazione predefinita; DATA_DIR e le opzioni
esplicite dei percorsi sostituiscono tale posizione.
Il comando termina con stato 0 quando non trova impedimenti, 1 quando il
rapporto è completo ma esistono impedimenti al ripristino e 2 per argomenti non validi
o un errore imprevisto di raccolta. Usa --data-dir PATH o --database PATH
per esaminare una posizione non predefinita. Un inventario di volume predefinito o con --data-dir
accetta solo il file canonico DATA_DIR/data.sqlite e rifiuta le voci database/WAL/SHM
con hard link, collegamenti simbolici o che non siano file regolari. Un percorso --database
esplicito può trovarsi fuori da DATA_DIR, ma il database selezionato e gli eventuali file associati
devono comunque essere file regolari e non possono essere collegamenti simbolici. Quando --database viene usato
senza --data-dir, il ripristino considera la directory superiore del database come radice dei dati,
così chiave, blob e definizioni dei plugin corrispondenti vengono inventariati insieme.
Il runtime legge inoltre le definizioni storiche dei plugin dalla directory deterministica plugins
del pacchetto backend e, per un PLUGINS_DIR relativo, dalla posizione storica relativa
al backend. Il ripristino inventaria questi percorsi legacy attivi e impedisce un'istantanea del solo volume
quando contengono definizioni personalizzate. Le distribuzioni pacchettizzate possono specificare
--legacy-plugins-dir PATH più volte quando la disposizione dell'immagine sposta tali
directory di compatibilità.
Per la distribuzione Compose privata, eseguilo all'interno del container distribuito, affinché il rapporto descriva volume montato, codice e secret di quel container:
docker exec libre-webui \
libre-webui recovery-check --json --data-dir /app/backend/data
Che cosa controlla l'inventario
Il rapporto JSON con versione registra:
- le versioni di applicazione, Node.js, sistema operativo e architettura;
- le dimensioni del file SQLite e di WAL/SHM,
quick_check, convalida delle chiavi esterne, impronta dello schema, versione utente, tabelle obbligatorie mancanti e convalida senza seguire link del file sorgente prima di creare un'istantanea privata di ispezione; - leggibilità e scrivibilità della directory dei dati, numero di file e numero di byte;
- la fonte della chiave di cifratura selezionata e un'impronta unidirezionale di 16 caratteri;
- la convalida senza seguire link e a collegamento singolo del file persistente
.encryption_key; - presenza, quantità, dimensioni e inclusione nella directory dei dati delle definizioni personalizzate dei plugin, oltre a radice crittografata dei blob locali, contenuti multimediali incorporati, riferimenti vocali, testo dei documenti, vettori legacy dei documenti e vettori della piattaforma con relative righe ACL/filtro;
- l'autenticazione limitata e in sola lettura di ogni oggetto blob locale canonico e di ogni envelope incorporato dei vettori della piattaforma, inclusa la verifica completa di segmenti/checksum dei blob e la disponibilità della chiave configurata;
- l'autenticazione limitata e in sola lettura di ogni envelope AES-GCM riconoscibile di testo legacy in chat, note, documenti, preferenze, secret dei plugin, stato galleria/multimedia ed email dell'account, oltre a ogni envelope legato con AAD per nome della voce salvata, registrazione e trascrizione;
- conteggi di attività/esecuzioni/anteprime Work e volumi Docker, PVC Kubernetes o identità hash dei percorsi host previsti; i volumi Docker devono recare sia l'etichetta gestita sia l'ID esatto dell'attività proprietaria;
- stati dei job legacy di generazione multimediale, più job duraturi per stato, tentativi per risultato, conteggi di flusso eventi/eventi e ultimo cursore eventi globale;
- l'autenticazione limitata e in sola lettura di ogni payload crittografato di job ed evento duraturo, oltre alla convalida sintattica limitata di ogni payload di riferimento opaco; e
- impedimenti espliciti, avvisi e dati che risiedono fuori dalla directory dei dati dell'applicazione.
Il rapporto non include mai chiavi di cifratura, secret JWT/sessione, credenziali dei provider, contenuti dei plugin, contenuti degli utenti o percorsi letterali delle aree di lavoro host. Vengono emessi solo valori booleani sulla presenza dei secret e l'impronta non reversibile della chiave di cifratura.
Un mount dei dati in sola lettura è valido per l'ispezione di ripristino e produce un avviso, non un impedimento. La disponibilità dell'applicazione richiede comunque uno spazio scrivibile; non avviare mai Libre WebUI sull'istantanea in sola lettura usata dall'utilità di backup.
Impedimenti
Considera qualsiasi impedimento come un controllo di ripristino non superato. Tra gli impedimenti tipici vi sono un database mancante o danneggiato, uno schema incompleto, una chiave assente/in conflitto, testo cifrato legacy o della piattaforma danneggiato o non autenticato, limiti di verifica superati, una directory dei dati illeggibile, una sorgente SQLite collegata o non regolare, esecuzioni o anteprime Work attive, job multimediali o duraturi, un'area di lavoro Work mancante o con etichetta errata, mancata corrispondenza delle intestazioni o lacune di sequenza degli eventi duraturi, definizioni di plugin personalizzate fuori dalla directory dei dati oppure un piano di controllo del runtime incapace di verificare le aree di lavoro esterne. Arresta le attività in corso e risolvi le dipendenze mancanti prima di creare l'istantanea; non modificare il rapporto per nascondere un impedimento.
I payload duraturi crittografati vengono autenticati rispetto all'identità del relativo job/evento
e convalidati come JSON canonico limitato. I payload di riferimento opachi sono solo sottoposti
a limiti e controllo sintattico: il substrato attuale non dispone di un repository autorevole
dei riferimenti ai blob con cui il ripristino possa dimostrare l'esistenza o l'accesso della destinazione.
Il rapporto contrassegna referenceTargetsVerified come false e avvisa ogni volta che tali
riferimenti sono presenti; non espone mai i valori dei payload o dei riferimenti.
I campi di testo legacy precedono un indicatore obbligatorio dell'envelope, quindi le righe realmente in testo normale
delle generazioni precedenti dello schema rimangono leggibili e non vengono indicate come testo cifrato autenticato.
Gli envelope canonici vengono sempre autenticati; i valori in tre parti con IV o tag di autenticazione
della larghezza di un envelope si chiudono in caso di malformazione. I campi delle voci salvate dispongono di un envelope
binario non ambiguo e devono sempre autenticarsi rispetto a identità di profilo,
proprietario e campo. La sezione JSON encryption.legacyCiphertext segnala i totali di record
e byte di testo/binari autenticati senza esporre il testo normale.
Quando è presente la colonna users.email_lookup dello schema v4, il ripristino autentica anche
ogni email non null e ricalcola il relativo token di ricerca con chiave e separazione di dominio.
Un token mancante o non corrispondente, oppure collegato a un'email null, impedisce l'istantanea.
I database precedenti alla v4 rimangono compatibili perché non dispongono di questa colonna di ricerca derivata.
Limite attuale del backup
L'utilità della distribuzione privata arresta l'applicazione se era in esecuzione e usa l'immagine
immutabile, il volume dati montato e l'ambiente di quel container per creare un archivio solo
integrato. Il manifest è firmato con Ed25519 e l'intero payload è cifrato con una chiave di backup
AES-256-GCM detenuta dall'operatore. Contiene SQLite, blob locali e vettori incorporati,
selettori del runtime e configurazione protetta necessaria a decifrare lo stato ripristinato.
L'utilità verifica firma, checksum del testo cifrato e payload decifrato prima di pubblicare
l'archivio e il rapporto dei metadati. libre-webui-restore accetta solo un volume Docker
nuovo, verifica l'inventario di ripristino decifrato prima di copiare dati e pubblica
la configurazione recuperata come file privati in una nuova directory di destinazione.
La configurazione protetta del runtime include timeout di pool, connessione, inattività, istruzioni
e blocco della migrazione PostgreSQL; timeout di connessione Redis; entrambe le impostazioni della quota
duratura dei blob; selettori della piattaforma; prefisso S3 e modalità di indirizzamento.
Questi valori si trovano nel payload firmato e cifrato, non nel manifest in testo normale, e vengono
ripubblicati come configurazione in modalità 0600 durante un ripristino applicato.
L'archivio solo non include volumi Docker Work, PVC Kubernetes, cartelle dell'area di lavoro associate all'host, modelli Ollama o stato dei provider esterni. Mantieni visibili nel manifest firmato tali esclusioni e crea separatamente l'istantanea dello spazio Work esterno. Il profilo team usa un flusso offline distinto: un'istantanea PostgreSQL esportata, oggetti di testo cifrato S3 esatti con versione, inventario PGVector, configurazione del runtime e identità della chiave vengono sigillati nello stesso formato di archivio firmato/cifrato e verificati rispetto a una destinazione PostgreSQL/S3 pulita durante il ripristino. Cache, presenza, riattivazioni e lease Redis vengono ricostruiti dallo stato SQL canonico.
Il backup team autentica inoltre ogni payload crittografato limitato di job ed eventi duraturi
nell'esatta istantanea PostgreSQL esportata. Il relativo inventario firmato protetto registra i totali
di job, eventi, flussi, cursori, envelope, riferimenti e testo normale autenticato. Ogni flusso
di eventi deve contenere esattamente la sequenza contigua 1..last_sequence e la sequenza globale
dei cursori di PostgreSQL non deve essere inferiore al cursore archiviato più elevato. Il ripristino
ripete questi controlli sulla destinazione pulita e richiede che il risultato completo corrisponda
all'inventario sorgente firmato prima di segnalare il successo. Le lacune tra distinti valori del cursore
globale sono valide, perché l'allocazione delle identità PostgreSQL non è transazionale; le sequenze
per flusso sono il contratto di ordinamento contiguo.
Quando PLUGINS_DIR punta fuori da DATA_DIR, il ripristino inventaria esattamente tale
directory e la contrassegna come esclusa dall'archivio del volume dell'applicazione. Qualsiasi definizione
presente impedisce l'istantanea del solo volume finché l'operatore non predispone un'istantanea corrispondente
della directory dei plugin. La stessa regola si applica alle directory legacy attive dei plugin. Le definizioni
JSON con collegamenti simbolici, non regolari o illeggibili costituiscono sempre impedimenti e non vengono mai seguite
o omesse senza avviso.
I job duraturi e gli eventi ordinati sono attivi in entrambi i profili. Il ripristino viene bloccato mentre è attivo un tentativo di job o un'esecuzione Work, convalida i payload di job/eventi e le intestazioni contigue dei flussi e ne conserva lo stato SQL canonico. Il profilo solo esegue il worker incorporato e limitato; il profilo team esegue gli stessi gestori registrati in un worker esterno e usa Redis solo per riattivazione e distribuzione.
Per la produzione, archivia i secret di cifratura e JWT in un gestore di secret protetto, mantieni gli archivi di backup fuori dall'host e cifrati e prova i ripristini in un ambiente compatibile e pulito. L'inventario è un'istantanea preliminare dello stato noto, non un blocco di manutenzione né una prova indipendente che ogni risorsa esterna possa essere ripristinata.
Comandi per backup firmati e cifrati
Gli esempi seguenti usano il comando libre-webui installato globalmente tramite npm o
Homebrew. Senza installazione globale, sostituisci libre-webui con
npx --yes libre-webui@latest. Da un checkout dei sorgenti, crea una volta il backend
e sostituisci libre-webui backup con npm run recovery:backup --.
L'immagine Docker di produzione espone lo stesso comando in
/usr/local/bin/libre-webui. Backup e ripristino team richiedono inoltre
pg_dump e pg_restore di PostgreSQL 16; sono inclusi nell'immagine di produzione
e nel percorso dei comandi della formula Homebrew. Installa esplicitamente un client PostgreSQL
compatibile prima di usare questi comandi da npm/npx semplice.
Genera la chiave di archivio AES-256-GCM detenuta dall'operatore e la coppia di chiavi di firma Ed25519 in una directory privata, quindi sposta le chiavi private in uno spazio protetto fuori dall'host:
install -d -m 0700 /absolute/private/libre-backup-keys
libre-webui backup keygen \
--directory /absolute/private/libre-backup-keys
Per una directory dati solo inattiva, crea e verifica in modo indipendente un archivio:
libre-webui backup create \
--offline \
--data-dir /absolute/path/to/libre-data \
--output /absolute/backups/libre-solo.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-private-key /absolute/private/libre-backup-keys/backup-signing-private.pem
libre-webui backup verify \
--archive /absolute/backups/libre-solo.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem
Esegui prima un controllo preliminare del ripristino, quindi applicalo soltanto a una directory di destinazione nuova e vuota:
libre-webui backup restore-preflight \
--archive /absolute/backups/libre-solo.lwbackup \
--target /absolute/restore/libre-data \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem
libre-webui backup restore-apply \
--archive /absolute/backups/libre-solo.lwbackup \
--target /absolute/restore/libre-data \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem
libre-webui backup restore-verify \
--target /absolute/restore/libre-data
Per la modalità team, arresta tutte le repliche e i worker dell'applicazione, mantieni caricato l'ambiente PostgreSQL/S3/portachiavi sorgente e crea l'archivio coordinato:
libre-webui backup create-team \
--offline \
--output /absolute/backups/libre-team.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-private-key /absolute/private/libre-backup-keys/backup-signing-private.pem
Prima del ripristino, carica le variabili d'ambiente per un database PostgreSQL distinto e vuoto e un bucket S3 vuoto con controllo delle versioni. Il controllo preliminare verifica firma e archivio cifrato, convalida l'inventario protetto e dimostra che il database di destinazione e il prefisso del bucket selezionati sono vuoti, senza pubblicare dati. L'applicazione ripristina in tali destinazioni pulite, verifica schema PostgreSQL, oggetti S3 esatti e record PGVector risultanti e scrive la configurazione protetta del runtime in una nuova directory privata:
libre-webui backup restore-team-preflight \
--archive /absolute/backups/libre-team.lwbackup \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem
libre-webui backup restore-team-apply \
--archive /absolute/backups/libre-team.lwbackup \
--configuration-output /absolute/restore/libre-team-config \
--encryption-key /absolute/private/libre-backup-keys/backup-encryption.key \
--signing-public-key /absolute/private/libre-backup-keys/backup-signing-public.pem
Non indirizzare mai un ripristino al database sorgente, al bucket sorgente, a una directory dati esistente o a una directory di configurazione contenente file. Conserva la chiave di firma pubblica insieme alla procedura di ripristino; il possesso del solo archivio e della chiave pubblica non consente di decifrare il payload.
Se il ripristino team segnala un rollback incompleto, considera entrambe le destinazioni selezionate
come contaminate e non riprovare immediatamente. Esamina e pulisci il database PostgreSQL di destinazione,
quindi elenca e rimuovi ogni versione di oggetto e marcatore di eliminazione sotto l'esatto prefisso S3
di destinazione. Esegui nuovamente restore-team-preflight; è sicuro ritentare l'applicazione soltanto
dopo che il controllo preliminare della destinazione pulita è riuscito.
Esercitazioni pianificate e verificate di ripristino
I backup mai ripristinati sono una speranza, non una procedura di ripristino. Un'esercitazione dimostra che l'istanza sia effettivamente ripristinabile eseguendo dall'inizio alla fine l'esatta pipeline precedente, senza tempi di inattività e senza intervento dell'operatore:
- Viene preparata un'istantanea inattiva della directory dei dati: il database SQLite
tramite l'API di backup online, blob e file tramite copia fisica. L'esercitazione
attende un momento di inattività: rifiuta di essere eseguita mentre un job duraturo è in corso,
la stessa regola applicata da
recovery-check. - La copia preparata diventa un archivio firmato e cifrato con AES-256-GCM usando chiavi temporanee per l'esercitazione, ed esegue l'inventario di ripristino completo.
- L'archivio viene verificato, ripristinato in una destinazione temporanea isolata e l'ambiente ripristinato viene verificato nuovamente.
- L'esercitazione registra ciò che ha misurato: la durata del ripristino è l'RTO dimostrato e l'intervallo tra esercitazioni riuscite limita l'RPO raggiungibile della pianificazione corrente; quindi elimina ogni artefatto. Le esercitazioni sono verifiche, non backup: non viene conservato alcun archivio o chiave.
Abilita la pianificazione con RECOVERY_DRILL_INTERVAL_HOURS (ad esempio 24);
le esercitazioni vengono quindi eseguite sul pianificatore condiviso con un lease di coordinamento, così
repliche e tick sovrapposti non possono duplicarne l'esecuzione. La pagina Sistema mostra la
cronologia delle esercitazioni con un pulsante "Esegui esercitazione ora" per gli amministratori, basato su
GET /api/recovery/drills e POST /api/recovery/drills/run. Un'esercitazione
automatica non riuscita avvisa ogni amministratore tramite la casella delle notifiche
(e le eventuali destinazioni webhook iscritte); le esecuzioni manuali comunicano direttamente
il rifiuto. RECOVERY_DRILL_HISTORY limita la cronologia conservata
(60 voci per impostazione predefinita).
Le esercitazioni coprono il profilo solo (SQLite), in cui l'archivio del file system è il
percorso di backup autorevole. Il profilo team mantiene il flusso coordinato
backup create-team, la cui prova di ripristino rimane per ora un passaggio della procedura
dell'operatore.