Un punto de recuperación debe restaurar la base de datos completa. Las copias de seguridad JSON de EmDash sirven para inspección y herramientas personalizadas, pero EmDash no puede restaurarlas. Use una copia de seguridad en bruto de la base de datos o la recuperación a un punto en el tiempo antes de una migración de base de datos o de una operación destructiva.
Haga una copia de seguridad de los binarios de medios por separado. Si el sitio almacena ajustes de plugin cifrados, conserve la lista completa de rotación de EMDASH_ENCRYPTION_KEY en una copia de seguridad separada del gestor de secretos. Las copias de seguridad y las exportaciones de la base de datos no contienen esos archivos ni esas claves.
Elegir un método de recuperación
Use el método que corresponda al adaptador de base de datos configurado del sitio:
| Base de datos | Punto de recuperación |
|---|---|
| Cloudflare D1 | Registre un marcador de Time Travel. Cree un volcado SQL externo cuando la retención requerida supere la de Time Travel o cuando se necesite un ensayo de restauración. |
| SQLite o libSQL local | Use el comando de copia de seguridad en línea de SQLite y ejecute después una comprobación de integridad sobre la copia. |
| PostgreSQL | Use la recuperación a un punto en el tiempo del proveedor o cree un archivo en formato personalizado con pg_dump. |
| Hyperdrive | Haga la copia de seguridad de su origen PostgreSQL mediante una conexión directa al origen. Un binding de Hyperdrive no es una conexión de copia de seguridad. |
| libSQL alojado en Turso | Use la recuperación a un punto en el tiempo de Turso o cree y ensaye un volcado SQL. |
| Otro proveedor remoto de libSQL | Use el procedimiento de exportación de la base de datos completa o de recuperación a un punto en el tiempo del proveedor y pruébelo contra una base de datos aislada. |
Conserve el punto de recuperación junto con el artefacto de aplicación correspondiente, la copia de seguridad de medios y la versión de la lista de claves. Antes de una migración planificada, registre la base de datos y el entorno exactos, detenga las escrituras de la aplicación cuando el procedimiento del proveedor lo exija y confirme que el punto de recuperación seguirá disponible durante la ventana de reversión prevista.
Respaldar y restaurar objetos de medios
Los buckets de R2 y compatibles con S3 necesitan una copia de seguridad a nivel de objeto además de la base de datos. El siguiente comando de AWS CLI copia todos los objetos, incluidos los archivos JSON de EmDash bajo backups/, a un directorio local de copia de seguridad. En AWS S3, omita --endpoint-url.
aws s3 sync s3://emdash-media ./emdash-media-backup \
--endpoint-url https://<account-id>.r2.cloudflarestorage.com
Sustituya <account-id> por el ID de la cuenta de Cloudflare. Use credenciales de bucket de solo lectura para las tareas de copia de seguridad rutinarias. Almacene la copia fuera de la cuenta de producción o del dominio de fallo, y registre el punto de recuperación de la base de datos creado al mismo tiempo.
Restaure en un bucket de recuperación vacío en lugar de sobrescribir producción mientras atiende solicitudes:
aws s3 sync ./emdash-media-backup s3://emdash-media-recovery \
--endpoint-url https://<account-id>.r2.cloudflarestorage.com
Dé a la tarea de restauración acceso de escritura solo al bucket de recuperación. Apunte un despliegue que no sea de producción a la base de datos y al bucket restaurados, abra varias URL de medios conocidas y suba y elimine un archivo desechable. Cambie el binding de producción o la configuración del bucket solo después de que la base de datos y los medios superen juntos sus comprobaciones.
Para el almacenamiento local, copie el directorio configurado por el adaptador de almacenamiento local(). Detenga las escrituras de medios mientras lo copia y después verifique archivos representativos de la copia.
Recuperar una base de datos D1 con Time Travel
Antes de una migración, pida a Time Travel el marcador actual de la base de datos y registre la salida completa junto con el despliegue:
npx wrangler d1 time-travel info my-database
Los puntos de recuperación de Time Travel caducan. Cloudflare los conserva actualmente durante 7 días en el plan Workers Free y 30 días en el plan Workers Paid. Cree un volcado D1 externo cuando la ventana de reversión deba durar más.
Si hace falta recuperar, detenga las escrituras en el sitio y restaure el marcador exacto registrado antes de la migración:
npx wrangler d1 time-travel restore my-database \
--bookmark="<pre-migration-bookmark>"
Sustituya <pre-migration-bookmark> por el marcador registrado. El comando sobrescribe la base de datos en su sitio y cancela las consultas en curso. Guarde el marcador anterior que imprime el comando de restauración para poder deshacer la propia restauración.
Time Travel restaura el contenido, los usuarios, los ajustes, los datos de plugins y los registros de migración. No restaura los objetos de medios de R2 ni EMDASH_ENCRYPTION_KEY. Restaure el artefacto de aplicación, los medios y las claves correspondientes antes de reabrir el tráfico. Verifique el inicio de sesión, la lectura de contenido, el esquema, un ajuste de plugin cifrado y una escritura.
Consulte la documentación de D1 Time Travel para conocer la retención, los requisitos y el comportamiento de restauración vigentes.
Crear un volcado D1 externo
Para un volcado SQL de la base de datos en bruto (incluidas las tablas de usuarios y autenticación), use Wrangler. Un simple wrangler d1 export my-database --remote falla con D1 Export error: cannot export databases with Virtual Tables (fts5) en cuanto alguna colección tiene la búsqueda activada, porque EmDash guarda su índice de búsqueda en tablas virtuales FTS5. Exporte las demás tablas por nombre y deje fuera el índice de búsqueda; el sitio restaurado lo reconstruye.
El volcado se divide en cuatro archivos para que la restauración tenga éxito:
backup-schema.sqlcrea las tablas.backup-folders.sqlcontiene las carpetas de medios. Las importaciones grandes se ejecutan por partes, de modo que un elemento multimedia se insertaría antes que la carpeta a la que pertenece y fallaría la comprobación de la clave externa.backup-data.sqlcontiene todas las demás filas.backup-indexes.sqlcontiene los índices y los triggers, que una exportación por nombre de tabla deja fuera. Se crean al final para que los triggers no se disparen mientras se importan las filas.
Estos comandos requieren jq. Los siguientes comandos escriben los cuatro archivos:
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 la documentación de importación y exportación de D1 para conocer las opciones y los límites de exportación de Wrangler.
Conserve los archivos SQL junto con la versión de la aplicación correspondiente, la copia de seguridad de medios creada al mismo tiempo y una copia almacenada por separado de la lista de rotación de EMDASH_ENCRYPTION_KEY. Pruebe la recuperación importando los archivos en una base de datos D1 vacía recién aprovisionada, restaurando las claves de runtime, actualizando un binding que no sea de producción para que apunte a esa base de datos y verificando el sitio.
Importe los archivos en la base de datos de recuperación vacía en este orden:
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
La base de datos restaurada no tiene índice de búsqueda. EmDash lo reconstruye la primera vez que se llama a la API de búsqueda (/_emdash/api/search) en el sitio restaurado, por ejemplo desde la paleta de comandos de la administración o desde un cuadro de búsqueda que use la API. Hasta entonces, las páginas que llaman a search() directamente no devuelven resultados. Para reconstruirlo de inmediato, solicite /_emdash/api/search?q=a una vez que el sitio esté en marcha.
Respaldar SQLite y libSQL local
Para una copia de seguridad sin conexión, detenga todos los procesos que escriben en la base de datos y copie el archivo de la base de datos junto con los archivos -wal y -shm que haya a su lado. El archivo -wal puede contener cambios confirmados que todavía no están en el archivo principal.
Para una copia de seguridad en línea consistente, use el comando de copia de seguridad de SQLite sobre la ruta configurada por el adaptador de base de datos:
sqlite3 emdash.db ".backup backup.db"
Compruebe la base de datos copiada. El comando debe imprimir ok:
sqlite3 backup.db "PRAGMA integrity_check"
Abra la copia con la versión de la aplicación correspondiente en un entorno que no sea de producción y verifique el inicio de sesión, el contenido público, un ajuste de plugin cifrado, una edición y una lectura de medios.
Para recuperar, detenga todos los procesos que escriben en la base de datos, conserve una copia de la base de datos dañada y de sus archivos -wal y -shm, sustitúyala por la copia de seguridad verificada y restaure el artefacto de aplicación, los medios y las claves correspondientes antes de reabrir el tráfico.
Respaldar PostgreSQL y Hyperdrive
Use la recuperación a un punto en el tiempo o la función de snapshots del proveedor de PostgreSQL cuando ofrezca una restauración aislada que se pueda probar antes de modificar producción. Registre su marca de tiempo o ID de snapshot exactos y el período de retención.
Para una copia de seguridad portátil, conéctese directamente al origen de PostgreSQL y cree un archivo en formato personalizado:
pg_dump --format=custom --file=emdash.dump "$DATABASE_URL"
pg_dump crea un archivo transaccionalmente consistente mientras la base de datos sigue en uso. Inspeccione la tabla de contenidos del archivo antes de confiar en él:
pg_restore --list emdash.dump > emdash.dump.list
Aprovisione una base de datos de recuperación vacía. Conéctese como el rol de aplicación canónico de EmDash y restaure sin trasladar la propiedad del origen a la base de datos de recuperación:
pg_restore --exit-on-error --no-owner \
--dbname="$RECOVERY_DATABASE_URL" emdash.dump
El rol de RECOVERY_DATABASE_URL pasa a ser propietario de los objetos de EmDash restaurados. Use el mismo rol estable que usará la aplicación recuperada. Apunte un despliegue que no sea de producción a la base de datos de recuperación y verifique el inicio de sesión, la lectura de contenido, el esquema, un ajuste de plugin cifrado y una escritura.
Con Hyperdrive, DATABASE_URL debe ser la conexión directa al origen de PostgreSQL que indica migrationConnectionStringEnv; el binding del Worker no se puede pasar a las herramientas de copia de seguridad de PostgreSQL. Siga el procedimiento de recuperación del proveedor del origen y conserve la configuración de Hyperdrive junto con el artefacto de aplicación.
Consulte la documentación de copias de seguridad de PostgreSQL para la recuperación gestionada por el proveedor, las bases de datos grandes y el archivado continuo.
Respaldar libSQL alojado en Turso
La recuperación a un punto en el tiempo de Turso crea una base de datos independiente a partir de una marca de tiempo anterior. Registre una marca de tiempo RFC 3339 inmediatamente antes de la migración. Si hace falta recuperar, cree una base de datos aislada a partir de ese punto:
turso db create emdash-recovery \
--from-db emdash-production \
--timestamp <pre-migration-rfc3339-timestamp>
Sustituya <pre-migration-rfc3339-timestamp> por la marca de tiempo registrada. Cree un token para la base de datos recuperada, apunte a ella un despliegue que no sea de producción y verifique el sitio antes de cambiar la conexión de producción. Consulte la recuperación a un punto en el tiempo de Turso para conocer la retención que ofrece el plan del sitio.
Para una copia externa, haga un volcado de la base de datos completa:
turso db shell emdash-production .dump > emdash.sql
Pruebe el volcado creando a partir de él una base de datos aislada:
turso db create emdash-recovery --from-dump ./emdash.sql
Con otro proveedor remoto de libSQL, siga su procedimiento de exportación de la base de datos completa o de recuperación a un punto en el tiempo. No aplique una migración remota hasta que ese procedimiento haya producido un punto de recuperación y se haya probado una restauración aislada.
Usar copias de seguridad JSON para inspección
Una copia de seguridad JSON incluye:
- Todas las entradas de contenido, incluidos borradores, publicaciones programadas y elementos de la papelera
- Las definiciones de colecciones y campos que forman el modelo de contenido
- Las definiciones de taxonomías, los términos y los términos asignados a cada entrada
- Menús y elementos de menú, secciones, áreas de widgets y widgets, registros de SEO, historial de revisiones, metadatos de medios e historial de migraciones de la base de datos
- Ajustes del sitio como el título, el eslogan, la URL, la locale, el logotipo, las preferencias de visualización, los perfiles sociales y los valores SEO predeterminados, del grupo de ajustes
site:y de los ajustesemdash:site_title,emdash:site_taglineyemdash:locale
Omite:
- Cuentas de usuario, sesiones, passkeys, datos de OAuth, tokens de API y otros datos de autenticación
- El almacenamiento y los ajustes de los plugins, incluidos los secretos de los plugins
- Comentarios y reacciones, redirecciones y registros de 404, bylines, relaciones y referencias de contenido, registros de auditoría, límites de frecuencia y el estado de las tareas programadas
- Carpetas de medios, registros de dónde se usan los medios, subidas incompletas y los propios archivos de medios
En Settings → Backups, Download backup genera un archivo JSON nuevo. Back up now guarda uno bajo el prefijo backups/ cuando hay almacenamiento configurado. Estos archivos usan el mismo formato de snapshot versionado que las previsualizaciones de EmDash.
Para programar copias de seguridad JSON, active Daily automatic backups en Settings → Backups y elija una retención de 1 a 30 archivos. Se ejecutan durante el mantenimiento programado. En Cloudflare, el Worker necesita un cron trigger; en Node, el planificador integrado ejecuta la tarea.
Si el bucket tiene un dominio público de R2 o un origen de red de distribución de contenido, restrinja ese origen a los objetos de medios o sirva los medios a través de EmDash. La ruta de medios de EmDash se niega a servir backups/, pero el origen público de un bucket puede exponer todos los objetos mediante su URL.
Para copiar contenido, ajustes y medios a un sitio EmDash nuevo, use un paquete de sitio. Un paquete de sitio no restaura usuarios, tokens de API, datos de plugins ni secretos, por lo que no sustituye a un punto de recuperación de la base de datos.