Prontidão de recuperação
O Libre WebUI fornece um inventário de recuperação somente leitura como primeira barreira de segurança para backup e restauração. Ele informa qual estado conhecido existe e quais condições detectadas bloqueiam um snapshot. Ele não adquire um bloqueio de manutenção nem copia, criptografa, envia, exclui, repara ou restaura dados.
libre-webui recovery-check --json > recovery-inventory.json
Em um checkout do código-fonte, execute npm run build:backend uma vez e substitua
libre-webui recovery-check por npm run recovery:check --. Instalações distribuídas por npx e
Homebrew examinam ~/.libre-webui por padrão; DATA_DIR e opções de caminho explícitas
substituem esse local.
O comando termina com status 0 quando nenhum bloqueio é encontrado, 1 quando o
relatório está completo, mas há bloqueios de recuperação, e 2 para argumentos inválidos
ou falha inesperada na coleta. Use --data-dir PATH ou --database PATH
para examinar um local diferente do padrão. Um inventário padrão ou com --data-dir
aceita somente o arquivo canônico DATA_DIR/data.sqlite e rejeita entradas de banco de dados/WAL/SHM
com hard link, link simbólico ou que não sejam arquivos comuns. Um caminho explícito em --database
pode estar fora de DATA_DIR, mas o banco selecionado e seus arquivos complementares
ainda devem ser arquivos comuns e não podem ser links simbólicos. Quando --database é usado
sem --data-dir, a recuperação considera o diretório pai do banco como sua raiz de dados, para que
a chave, os blobs e as definições de plugins correspondentes sejam inventariados juntos.
O ambiente de execução também lê definições históricas de plugins no diretório determinístico
plugins do pacote de backend e, para um PLUGINS_DIR relativo, em seu
local histórico relativo ao backend. A recuperação inventaria esses caminhos legados ativos
e bloqueia um snapshot somente do volume quando eles contêm definições personalizadas.
Implantações empacotadas podem fornecer --legacy-plugins-dir PATH mais de uma vez quando
o layout da imagem move esses diretórios de compatibilidade.
Na implantação privada com Compose, execute o comando dentro do contêiner implantado para que o relatório descreva o volume montado, o código e os segredos desse contêiner:
docker exec libre-webui \
libre-webui recovery-check --json --data-dir /app/backend/data
O que o inventário verifica
O relatório JSON versionado registra:
- versões do aplicativo, Node.js, sistema operacional e arquitetura;
- arquivo SQLite e tamanhos de WAL/SHM,
quick_check, validação de chaves estrangeiras, impressão digital do esquema, versão do usuário, tabelas obrigatórias ausentes e validação sem seguir links dos arquivos-fonte antes da criação de um snapshot privado para inspeção; - legibilidade, capacidade de gravação, quantidade de arquivos e quantidade de bytes do diretório de dados;
- a fonte selecionada da chave de criptografia e uma impressão digital unidirecional de 16 caracteres;
- validação sem seguir links e de vínculo único para o arquivo persistente
.encryption_key; - presença, contagens, tamanhos e inclusão no diretório de dados das definições personalizadas de plugins, além da raiz criptografada de blobs locais, mídia incorporada, referências de voz, texto de documentos, vetores legados de documentos e vetores da plataforma com suas linhas de ACL/filtro;
- autenticação limitada e somente leitura de todos os objetos canônicos de blobs locais e de envelopes incorporados de vetores da plataforma, incluindo a verificação completa de trechos/checksums de blobs e a disponibilidade da chave configurada;
- autenticação limitada e somente leitura de todos os envelopes reconhecíveis legados de texto AES-GCM em conversas, notas, documentos, preferências, segredos de plugins, estado de galeria/mídia e email da conta, além de cada envelope vinculado por AAD para nome, gravação e transcrição de voz salvos;
- contagens de tarefas/execuções/visualizações do Work e os volumes Docker, PVCs do Kubernetes ou identidades com hash de caminhos do host esperados; os volumes Docker devem conter tanto o rótulo gerenciado quanto o ID exato da tarefa proprietária;
- estados legados de tarefas de geração de mídia, além de tarefas duráveis por estado, tentativas por resultado, contagens de streams/eventos e o último cursor global de eventos;
- autenticação limitada e somente leitura de cada payload criptografado de tarefa durável e evento, além de validação sintática limitada de todos os payloads de referência opacos; e
- bloqueios explícitos, avisos e dados que ficam fora do diretório de dados do aplicativo.
O relatório nunca inclui chaves de criptografia, segredos JWT/de sessão, credenciais de provedores, conteúdo de plugins, conteúdo de usuários nem caminhos literais de espaços de trabalho do host. Somente valores booleanos sobre a presença de segredos e a impressão digital irreversível da chave de criptografia são emitidos.
Uma montagem de dados somente leitura é válida para inspeção de recuperação e gera um aviso, e não um bloqueio. A prontidão do aplicativo ainda exige armazenamento gravável; nunca inicie o Libre WebUI usando o snapshot somente leitura empregado pelo auxiliar de backup.
Bloqueios
Trate qualquer bloqueio como uma falha na barreira de recuperação. Bloqueios comuns incluem banco de dados ausente ou corrompido, esquema incompleto, chave ausente ou conflitante, ciphertext legado ou da plataforma corrompido ou não autenticado, limites de verificação excedidos, diretório de dados ilegível, fonte do SQLite vinculada ou que não seja arquivo comum, execuções ou visualizações ativas do Work, tarefas de mídia ou tarefas duráveis, espaço de trabalho do Work ausente ou rotulado incorretamente, divergências no cabeçalho dos eventos duráveis ou lacunas de sequência, definições personalizadas de plugins fora do diretório de dados ou um plano de controle do ambiente de execução incapaz de verificar espaços de trabalho externos. Interrompa de forma controlada o trabalho ativo e resolva as dependências ausentes antes de criar o snapshot; não edite o relatório para ocultar um bloqueio.
Os payloads duráveis criptografados são autenticados com base na identidade de sua tarefa/evento
e validados como JSON canônico e limitado. Os payloads de referência opacos são apenas limitados
e verificados sintaticamente: a base atual não possui um repositório autorizado de referências de blobs
com o qual a recuperação possa comprovar a existência ou o acesso ao destino.
O relatório marca referenceTargetsVerified como false e avisa sempre que essas
referências estão presentes; ele nunca expõe valores de payloads nem de referências.
Os campos de texto legados antecedem um marcador de envelope obrigatório; portanto, linhas genuínas em texto simples
de gerações antigas do esquema continuam legíveis e não são informadas como ciphertext
autenticado. Os envelopes canônicos sempre são autenticados;
valores de três partes com um IV ou uma tag de autenticação do tamanho de um envelope falham de forma fechada
quando malformados. Os campos de voz salvos têm um envelope binário inequívoco e sempre
precisam ser autenticados com base no perfil, proprietário e identidade do campo. A seção JSON
encryption.legacyCiphertext informa os totais de registros e bytes autenticados de texto/binário
sem expor texto simples.
Quando a coluna users.email_lookup do esquema v4 está presente, a recuperação também
autentica todos os emails não nulos e recalcula seu token de busca com chave e separação de domínio.
Um token ausente ou divergente, ou um token associado a um email nulo,
bloqueia o snapshot. Bancos anteriores à v4 continuam compatíveis porque não possuem
essa coluna de busca derivada.
Limite atual do backup
O auxiliar da implantação privada interrompe o aplicativo quando ele estava em execução e
usa a imagem imutável, o volume de dados montado e o ambiente desse contêiner para
criar um arquivo solo integrado. O manifesto é assinado com Ed25519, e o
payload completo é criptografado com uma chave de backup AES-256-GCM mantida pelo operador. Ele
contém o SQLite, blobs locais e vetores incorporados, seletores do ambiente de execução e a
configuração protegida necessária para descriptografar o estado restaurado. O auxiliar verifica
a assinatura, o checksum do ciphertext e o payload descriptografado antes de publicar
o arquivo e o relatório de metadados. libre-webui-restore aceita somente um novo
volume Docker, verifica o inventário de recuperação descriptografado antes de copiar quaisquer
dados e publica a configuração recuperada como arquivos privados em um novo diretório de destino.
A configuração protegida do ambiente de execução inclui os timeouts de pool, conexão,
inatividade, statement e bloqueio de migração do PostgreSQL; o timeout de conexão do Redis;
as duas configurações de cota de blobs duráveis; os seletores da plataforma; e o prefixo e
modo de endereçamento do S3. Esses valores ficam dentro do payload assinado e criptografado, e não
no manifesto em texto simples, e são republicados como configuração de modo 0600 em uma
restauração aplicada.
O arquivo solo não inclui volumes Docker do Work, PVCs do Kubernetes, pastas de espaços de trabalho vinculadas ao host, modelos do Ollama nem estado de provedores externos. Mantenha essas exclusões do manifesto assinado visíveis e crie snapshots do armazenamento externo do Work separadamente. O perfil equipe usa o fluxo offline separado para equipe: um snapshot exportado do PostgreSQL, objetos exatos e versionados de ciphertext no S3, inventário do PGVector, configuração do ambiente de execução e identidade da chave são selados no mesmo formato de arquivo assinado/criptografado e verificados em um destino PostgreSQL/S3 limpo durante a restauração. O cache, a presença, os wake-ups e as concessões do Redis são reconstruídos a partir do estado SQL canônico.
O backup de equipe também autentica todos os payloads criptografados e limitados de tarefas duráveis e eventos
no snapshot PostgreSQL exportado exato. Seu inventário assinado protegido registra os totais
de tarefas, eventos, streams, cursores, envelopes, referências e texto simples autenticado.
Cada stream de eventos deve conter exatamente a sequência contígua 1..last_sequence, e a
sequência global de cursores do PostgreSQL não pode estar atrás do maior cursor armazenado. A restauração
repete essas verificações no destino limpo e exige que o resultado completo corresponda ao inventário
de origem assinado antes de informar sucesso. Lacunas entre valores globais de cursores distintos
são válidas porque a alocação de identidades do PostgreSQL não é transacional;
as sequências por stream são o contrato de ordenação contígua.
Quando PLUGINS_DIR aponta para fora de DATA_DIR, a recuperação inventaria esse
diretório exato e o marca como excluído do arquivo do volume do aplicativo. Qualquer
definição existente nele bloqueia o snapshot somente do volume até que o operador providencie um
snapshot correspondente do diretório de plugins. A mesma regra se aplica a diretórios legados ativos
de plugins. Definições JSON com link simbólico, que não sejam arquivos comuns ou que estejam ilegíveis
sempre são bloqueios; elas nunca são seguidas nem omitidas silenciosamente.
As tarefas duráveis e os eventos ordenados estão ativos nos dois perfis. A recuperação bloqueia enquanto uma tentativa de tarefa ou execução do Work está ativa, valida os payloads de tarefas/eventos e os cabeçalhos contíguos dos streams e preserva seu estado SQL canônico. O perfil solo executa o worker incorporado limitado; o perfil equipe executa os mesmos manipuladores registrados em um worker externo e usa o Redis somente para wake-up e fan-out.
Em produção, armazene os segredos de criptografia e JWT em um gerenciador de segredos protegido, mantenha os arquivos de backup fora do host e criptografados e teste restaurações em um ambiente compatível limpo. O inventário é uma verificação prévia do estado conhecido, e não um bloqueio de manutenção nem uma prova independente de que todos os recursos externos podem ser restaurados.
Comandos de backup assinado e criptografado
Os exemplos abaixo usam o comando libre-webui instalado pelo npm global ou
Homebrew. Sem instalação global, substitua libre-webui por
npx --yes libre-webui@latest. Em um checkout do código-fonte, compile o backend uma vez
e substitua libre-webui backup por npm run recovery:backup --.
A imagem Docker de produção disponibiliza o mesmo comando em
/usr/local/bin/libre-webui. O backup e a restauração de equipe também exigem
pg_dump e pg_restore do PostgreSQL 16; eles estão incluídos na imagem de produção
e no caminho de comandos da fórmula do Homebrew. Instale explicitamente um cliente
PostgreSQL compatível antes de usar esses comandos a partir do npm/npx comum.
Gere a chave de arquivo AES-256-GCM mantida pelo operador e o par de chaves de assinatura Ed25519 em um diretório privado e, depois, mova as chaves privadas para um armazenamento protegido fora do host:
install -d -m 0700 /absolute/private/libre-backup-keys
libre-webui backup keygen \
--directory /absolute/private/libre-backup-keys
Para um diretório de dados solo em estado quiescente, crie e verifique de forma independente um arquivo:
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
Primeiro, faça uma verificação prévia da restauração; aplique-a somente a um diretório de destino novo e vazio:
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
No modo equipe, interrompa todas as réplicas e workers do aplicativo, mantenha o ambiente de origem do PostgreSQL/S3/keyring carregado e crie o arquivo coordenado:
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
Carregue as variáveis de ambiente para um banco PostgreSQL diferente e vazio e um bucket S3 vazio e versionado antes da restauração. A verificação prévia confere a assinatura e o arquivo criptografado, valida o inventário protegido e comprova que o banco de destino e o prefixo do bucket selecionados estão vazios sem publicar dados. A aplicação restaura nesses destinos limpos, verifica o esquema PostgreSQL resultante, os objetos S3 exatos e os registros do PGVector e grava a configuração protegida do ambiente de execução em um novo diretório privado:
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
Nunca aponte uma restauração para o banco de origem, o bucket de origem, um diretório de dados existente nem um diretório de configuração que contenha arquivos. Mantenha a chave pública de assinatura com o manual de restauração; possuir apenas o arquivo e a chave pública não permite descriptografar o payload.
Se a restauração de equipe informar que a reversão ficou incompleta, considere os dois destinos
selecionados sujos e não tente novamente de imediato. Examine e limpe o banco PostgreSQL
de destino e, depois, enumere e remova cada versão de objeto e marcador de exclusão
no prefixo S3 de destino exato. Execute restore-team-preflight novamente;
só é seguro repetir a aplicação quando essa verificação prévia de destino limpo for bem-sucedida.
Simulações agendadas e verificadas de recuperação
Backups que nunca foram restaurados são esperança, e não recuperação. Uma simulação comprova que a instância é realmente recuperável ao exercitar o pipeline exato acima, de ponta a ponta, sem indisponibilidade e sem operador:
- É preparada uma cópia quiescente do diretório de dados — o banco de dados
SQLite pela API de backup online, e os blobs e arquivos por cópia física.
A simulação aguarda um momento ocioso: ela se recusa a executar enquanto qualquer
tarefa durável estiver em andamento, a mesma regra aplicada por
recovery-check. - A cópia preparada se torna um arquivo assinado e criptografado com AES-256-GCM, usando chaves efêmeras da simulação e executando o inventário completo de recuperação.
- O arquivo é verificado, restaurado em um destino temporário isolado, e o ambiente restaurado é verificado novamente.
- A simulação registra o que mediu — a duração da restauração é o RTO demonstrado, e o intervalo entre simulações bem-sucedidas limita o RPO alcançável pela programação atual — e então exclui todos os artifacts. As simulações são verificações, não backups: nenhum arquivo nem chave é retido.
Ative a programação com RECOVERY_DRILL_INTERVAL_HOURS (por exemplo, 24);
as simulações serão executadas no agendador compartilhado sob uma concessão de coordenação, para que
réplicas e rodadas sobrepostas não executem duas vezes. A página Sistema mostra o
histórico das simulações com um botão "Executar simulação agora" para administradores, sustentado por
GET /api/recovery/drills e POST /api/recovery/drills/run. Uma simulação
que falhe sem supervisão avisa todos os administradores pela caixa de entrada de notificações
(e quaisquer destinos de webhook inscritos); execuções manuais informam diretamente
sua recusa. RECOVERY_DRILL_HISTORY limita o histórico retido
(padrão de 60 entradas).
As simulações cobrem o perfil solo (SQLite), no qual o arquivo do sistema de arquivos é o
caminho autoritativo de backup. O perfil equipe mantém seu fluxo coordenado
backup create-team, cuja simulação de restauração ainda é uma etapa manual do operador
por enquanto.