Um ponto de recuperação deve restaurar o banco de dados completo. Os backups JSON do EmDash são úteis para inspeção e ferramentas personalizadas, mas o EmDash não consegue restaurá-los. Use um backup bruto do banco de dados ou a recuperação em um ponto no tempo antes de uma migração de banco de dados ou de uma operação destrutiva.
Faça backup dos binários de mídia separadamente. Se o site armazena configurações de plugin criptografadas, mantenha a lista completa de rotação de EMDASH_ENCRYPTION_KEY em um backup separado do gerenciador de segredos. Os backups e as exportações do banco de dados não contêm esses arquivos nem essas chaves.
Escolher um método de recuperação
Use o método correspondente ao adaptador de banco de dados configurado do site:
| Banco de dados | Ponto de recuperação |
|---|---|
| Cloudflare D1 | Registre um bookmark do Time Travel. Crie um dump SQL offsite quando a retenção necessária exceder a do Time Travel ou quando for preciso ensaiar uma restauração. |
| SQLite ou libSQL local | Use o comando de backup online do SQLite e, em seguida, execute uma verificação de integridade na cópia. |
| PostgreSQL | Use a recuperação em um ponto no tempo do provedor ou crie um arquivo em formato custom com pg_dump. |
| Hyperdrive | Faça backup da origem PostgreSQL por uma conexão direta com a origem. Um binding do Hyperdrive não é uma conexão de backup. |
| libSQL hospedado na Turso | Use a recuperação em um ponto no tempo da Turso ou crie e ensaie um dump SQL. |
| Outro provedor remoto de libSQL | Use o procedimento do provedor para exportar o banco de dados completo ou para recuperação em um ponto no tempo e teste-o em um banco de dados isolado. |
Mantenha o ponto de recuperação junto com o artefato de aplicação correspondente, o backup de mídia e a versão da lista de chaves. Antes de uma migração planejada, registre o banco de dados e o ambiente exatos, interrompa as gravações da aplicação quando o procedimento do provedor exigir e confirme que o ponto de recuperação continua disponível durante a janela de rollback pretendida.
Fazer backup e restaurar objetos de mídia
Buckets R2 e compatíveis com S3 precisam de um backup em nível de objeto além do banco de dados. O comando AWS CLI a seguir copia todos os objetos, incluindo os arquivos JSON do EmDash em backups/, para um diretório local de backup. Para o AWS S3, omita --endpoint-url.
aws s3 sync s3://emdash-media ./emdash-media-backup \
--endpoint-url https://<account-id>.r2.cloudflarestorage.com
Substitua <account-id> pelo ID da conta da Cloudflare. Use credenciais de bucket somente leitura nos jobs de backup de rotina. Armazene o backup fora da conta de produção ou do domínio de falha e registre o ponto de recuperação do banco de dados criado ao mesmo tempo.
Restaure em um bucket de recuperação vazio em vez de sobrescrever a produção enquanto ela atende requisições:
aws s3 sync ./emdash-media-backup s3://emdash-media-recovery \
--endpoint-url https://<account-id>.r2.cloudflarestorage.com
Dê ao job de restauração acesso de gravação apenas ao bucket de recuperação. Aponte uma implantação de não produção para o banco de dados e o bucket restaurados, abra várias URLs de mídia conhecidas e envie e exclua um arquivo descartável. Altere o binding de produção ou a configuração do bucket somente depois que o banco de dados e a mídia passarem juntos nas verificações.
Para armazenamento local, copie o diretório configurado pelo adaptador de armazenamento local(). Interrompa as gravações de mídia durante a cópia e, em seguida, verifique arquivos representativos da cópia.
Recuperar um banco de dados D1 com Time Travel
Antes de uma migração, peça ao Time Travel o bookmark atual do banco de dados e registre a saída completa junto com a implantação:
npx wrangler d1 time-travel info my-database
Os pontos de recuperação do Time Travel expiram. Atualmente, a Cloudflare os retém por 7 dias no plano Workers Free e por 30 dias no plano Workers Paid. Crie um dump D1 offsite quando a janela de rollback precisar durar mais.
Se for necessária uma recuperação, interrompa as gravações no site e restaure exatamente o bookmark registrado antes da migração:
npx wrangler d1 time-travel restore my-database \
--bookmark="<pre-migration-bookmark>"
Substitua <pre-migration-bookmark> pelo bookmark registrado. O comando sobrescreve o banco de dados no local e cancela as consultas em andamento. Salve o bookmark anterior impresso pelo comando de restauração para que a própria restauração possa ser desfeita.
O Time Travel restaura conteúdo, usuários, configurações, dados de plugins e registros de migração. Ele não restaura objetos de mídia do R2 nem EMDASH_ENCRYPTION_KEY. Restaure o artefato de aplicação, a mídia e as chaves correspondentes antes de reabrir o tráfego. Verifique o login, a leitura de conteúdo, o esquema, uma configuração de plugin criptografada e uma gravação.
Consulte a documentação do D1 Time Travel para saber a retenção, os requisitos e o comportamento de restauração atuais.
Criar um dump D1 offsite
Para um dump SQL do banco de dados bruto (incluindo as tabelas de usuários e autenticação), use o Wrangler. Um simples wrangler d1 export my-database --remote falha com D1 Export error: cannot export databases with Virtual Tables (fts5) assim que qualquer coleção tem a busca habilitada, porque o EmDash mantém seu índice de busca em tabelas virtuais FTS5. Exporte as outras tabelas pelo nome e deixe o índice de busca de fora; o site restaurado o reconstrói.
O dump é dividido em quatro arquivos para que a restauração seja bem-sucedida:
backup-schema.sqlcria as tabelas.backup-folders.sqlcontém as pastas de mídia. Importações grandes são executadas em partes, então, de outra forma, um item de mídia seria inserido antes da pasta a que pertence e falharia na verificação da chave estrangeira.backup-data.sqlcontém todas as outras linhas.backup-indexes.sqlcontém os índices e os triggers, que uma exportação por nome de tabela deixa de fora. Eles são criados por último para que os triggers não sejam disparados enquanto as linhas são importadas.
Esses comandos exigem o jq. Os comandos a seguir gravam os quatro arquivos:
npx wrangler d1 execute my-database --remote --json \
--command "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT GLOB '_emdash_fts_*' AND name NOT GLOB 'sqlite_*' AND name NOT GLOB '_cf_*' AND name != 'media_folders'" \
| jq -r '.[0].results[] | "--table=" + .name' > backup-tables.txt
npx wrangler d1 export my-database --remote --no-data --output=backup-schema.sql \
--table=media_folders $(cat backup-tables.txt)
npx wrangler d1 export my-database --remote --no-schema --output=backup-folders.sql \
--table=media_folders
npx wrangler d1 export my-database --remote --no-schema --output=backup-data.sql \
$(cat backup-tables.txt)
npx wrangler d1 execute my-database --remote --json \
--command "SELECT sql FROM sqlite_master WHERE type IN ('index', 'trigger') AND sql IS NOT NULL AND name NOT GLOB '_emdash_fts_*' AND tbl_name NOT GLOB '_emdash_fts_*' AND tbl_name NOT GLOB '_cf_*'" \
| jq -r '.[0].results[] | .sql + ";"' > backup-indexes.sql
Consulte a documentação de importação e exportação do D1 para ver as opções e os limites de exportação do Wrangler.
Mantenha os arquivos SQL junto com a versão correspondente da aplicação, o backup de mídia criado ao mesmo tempo e uma cópia armazenada separadamente da lista de rotação de EMDASH_ENCRYPTION_KEY. Teste a recuperação importando os arquivos para um banco de dados D1 vazio recém-provisionado, restaurando as chaves de runtime, atualizando um binding de não produção para esse banco de dados e verificando o site.
Importe os arquivos no banco de dados de recuperação vazio nesta ordem:
npx wrangler d1 execute my-recovery-database --remote --file=backup-schema.sql
npx wrangler d1 execute my-recovery-database --remote --file=backup-folders.sql
npx wrangler d1 execute my-recovery-database --remote --file=backup-data.sql
npx wrangler d1 execute my-recovery-database --remote --file=backup-indexes.sql
O banco de dados restaurado não tem índice de busca. O EmDash o reconstrói na primeira vez que a API de busca (/_emdash/api/search) é chamada no site restaurado, por exemplo pela paleta de comandos da administração ou por uma caixa de busca que use a API. Até lá, as páginas que chamam search() diretamente não retornam resultados. Para reconstruí-lo imediatamente, solicite /_emdash/api/search?q=a uma vez depois que o site estiver em execução.
Fazer backup do SQLite e do libSQL local
Para um backup offline, interrompa todos os processos que gravam no banco de dados e copie o arquivo do banco de dados junto com quaisquer arquivos -wal e -shm ao lado dele. O arquivo -wal pode conter alterações confirmadas que ainda não estão no arquivo principal.
Para um backup online consistente, use o comando de backup do SQLite no caminho configurado pelo adaptador de banco de dados:
sqlite3 emdash.db ".backup backup.db"
Verifique o banco de dados copiado. O comando deve imprimir ok:
sqlite3 backup.db "PRAGMA integrity_check"
Abra a cópia com a versão correspondente da aplicação em um ambiente de não produção e verifique o login, o conteúdo público, uma configuração de plugin criptografada, uma edição e uma leitura de mídia.
Para recuperar, interrompa todos os processos que gravam no banco de dados, guarde uma cópia do banco de dados danificado e de seus arquivos -wal e -shm, substitua-os pelo backup verificado e restaure o artefato de aplicação, a mídia e as chaves correspondentes antes de reabrir o tráfego.
Fazer backup do PostgreSQL e do Hyperdrive
Use a recuperação em um ponto no tempo ou o recurso de snapshots do provedor PostgreSQL quando ele oferecer uma restauração isolada que possa ser testada antes de alterar a produção. Registre o timestamp ou o ID do snapshot exato e o período de retenção.
Para um backup portátil, conecte-se diretamente à origem PostgreSQL e crie um arquivo em formato custom:
pg_dump --format=custom --file=emdash.dump "$DATABASE_URL"
O pg_dump cria um arquivo transacionalmente consistente enquanto o banco de dados continua em uso. Inspecione o sumário do arquivo antes de confiar nele:
pg_restore --list emdash.dump > emdash.dump.list
Provisione um banco de dados de recuperação vazio. Conecte-se como o papel canônico da aplicação EmDash e restaure sem levar a propriedade da origem para o banco de dados de recuperação:
pg_restore --exit-on-error --no-owner \
--dbname="$RECOVERY_DATABASE_URL" emdash.dump
O papel em RECOVERY_DATABASE_URL torna-se o proprietário dos objetos EmDash restaurados. Use o mesmo papel estável que a aplicação recuperada usará. Aponte uma implantação de não produção para o banco de dados de recuperação e verifique o login, a leitura de conteúdo, o esquema, uma configuração de plugin criptografada e uma gravação.
Para o Hyperdrive, DATABASE_URL deve ser a conexão direta com a origem PostgreSQL indicada por migrationConnectionStringEnv; o binding do Worker não pode ser passado às ferramentas de backup do PostgreSQL. Siga o procedimento de recuperação do provedor da origem e mantenha a configuração do Hyperdrive junto com o artefato de aplicação.
Consulte a documentação de backup do PostgreSQL para recuperação gerenciada pelo provedor, bancos de dados grandes e arquivamento contínuo.
Fazer backup do libSQL hospedado na Turso
A recuperação em um ponto no tempo da Turso cria um banco de dados separado a partir de um timestamp anterior. Registre um timestamp RFC 3339 imediatamente antes da migração. Se for necessária uma recuperação, crie um banco de dados isolado a partir desse ponto:
turso db create emdash-recovery \
--from-db emdash-production \
--timestamp <pre-migration-rfc3339-timestamp>
Substitua <pre-migration-rfc3339-timestamp> pelo timestamp registrado. Crie um token para o banco de dados recuperado, aponte uma implantação de não produção para ele e verifique o site antes de alterar a conexão de produção. Consulte a recuperação em um ponto no tempo da Turso para saber a retenção oferecida pelo plano do site.
Para uma cópia offsite, faça o dump do banco de dados completo:
turso db shell emdash-production .dump > emdash.sql
Teste o dump criando um banco de dados isolado a partir dele:
turso db create emdash-recovery --from-dump ./emdash.sql
Para outro provedor remoto de libSQL, siga o procedimento dele para exportar o banco de dados completo ou para recuperação em um ponto no tempo. Não aplique uma migração remota até que esse procedimento tenha produzido um ponto de recuperação e uma restauração isolada tenha sido testada.
Usar backups JSON para inspeção
Um backup JSON inclui:
- Todas as entradas de conteúdo, incluindo rascunhos, posts agendados e itens da lixeira
- As definições de coleções e de campos que formam o modelo de conteúdo
- As definições de taxonomias, os termos e os termos atribuídos a cada entrada
- Menus e itens de menu, seções, áreas de widgets e widgets, registros de SEO, histórico de revisões, metadados de mídia e histórico de migrações do banco de dados
- Configurações do site, como título, slogan, URL, locale, logotipo, preferências de exibição, perfis sociais e padrões de SEO, do grupo de configurações
site:e das configuraçõesemdash:site_title,emdash:site_taglineeemdash:locale
Ele omite:
- Contas de usuário, sessões, passkeys, dados de OAuth, tokens de API e outros dados de autenticação
- O armazenamento e as configurações dos plugins, incluindo os segredos dos plugins
- Comentários e reações, redirecionamentos e logs de 404, bylines, relações e referências de conteúdo, logs de auditoria, limites de taxa e o estado das tarefas agendadas
- Pastas de mídia, registros de onde a mídia é usada, uploads incompletos e os próprios arquivos de mídia
Em Settings → Backups, Download backup gera um novo arquivo JSON. Back up now armazena um sob o prefixo backups/ quando o armazenamento está configurado. Esses arquivos usam o mesmo formato de snapshot versionado das prévias do EmDash.
Para agendar backups JSON, ative Daily automatic backups em Settings → Backups e escolha uma retenção de 1 a 30 arquivos. Eles são executados durante a manutenção agendada. Na Cloudflare, o Worker precisa de um cron trigger; no Node, o agendador integrado executa a tarefa.
Se o bucket tiver um domínio público do R2 ou uma origem de rede de entrega de conteúdo, restrinja essa origem aos objetos de mídia ou sirva a mídia pelo EmDash. A rota de mídia do EmDash se recusa a servir backups/, mas a origem pública de um bucket pode expor todos os objetos por URL.
Para copiar conteúdo, configurações e mídia para um novo site EmDash, use um pacote de site. Um pacote de site não restaura usuários, tokens de API, dados de plugins nem segredos, portanto não substitui um ponto de recuperação do banco de dados.