Backup y restore del estado de un agente IA: volúmenes, SQLite y S3
Resumen
Cómo no perder la memoria del agente al redeployar: backups nativos de Railway (schedules, límite 50% del volumen), copia consistente de SQLite con .backup o WAL, snapshots de volúmenes Docker y Fly, restore sin pisar producción, y copia offsite a S3/R2 porque borrar el volumen borra los backups nativos.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
Rollback devuelve el código anterior. No devuelve el sqlite que tu agente corrompió a las 2 AM. Si el estado vive en un volumen — memoria de sesión, RAG local, cola de jobs — necesitas backup y restore del dato, no solo del binario. Railway lo dice sin rodeos: borrar un volumen elimina todos sus backups nativos. Las fuentes oficiales fueron consultadas el 3 de septiembre de 2026.
Esta guía cubre el estado que duele perder: sqlite, archivos en /data, embeddings cacheados. No sustituye el backup del proveedor de Postgres gestionado — pero muchos agentes MVP empiezan con un archivo en disco.
La regla de dos capas
- Nativo de plataforma: snapshots Railway (daily/weekly/monthly), utilidades de volumen Fly/Docker.
- Offsite:
pg_dump,.backupde SQLite, orailway volume files uploadhacia S3/R2/Bucket — fuera del volumen que un CLI puede borrar.
Si solo tienes capa 1 y alguien ejecuta railway volume delete, pierdes código y historial. El self-hosting con Docker ya menciona cron de tarball; aquí va el procedimiento completo.
Qué respaldar en un agente
| Dato | Típico en | ¿Crítico? |
|---|---|---|
| sqlite / LevelDB de sesión | /data, volumen Railway | Sí — es la “memoria” |
| Índice vectorial local | mismo volumen | Sí — tarda en reindexar |
| Cola de jobs (BullMQ en Redis) | Redis gestionado o volumen | Depende — jobs en vuelo |
| Logs | stdout / plataforma | No para restore — ver logs |
| Secretos | env vars | No en el backup de disco — secretos |
No copies .env al bucket sin cifrar. El backup es del estado de negocio, no de las llaves.
Railway: backups de volumen
Con un volumen montado en el servicio del agente:
- Manual: pestaña Backups → Create backup.
- Programado: Daily / Weekly / Monthly.
- Restore: elige timestamp → Restore (mismo proyecto y environment).
- Costo: incremental copy-on-write, facturado como volumen.
- Límite: backup manual ≤ 50 % de la capacidad del volumen — si tu sqlite creció, agranda el volumen antes.
Railway CLI para archivos sueltos:
railway volume files list /
railway volume files download /data/agent.db ./agent-$(date +%F).db
Importante: el volumen se monta al arrancar el contenedor, no en build. Escribe en la ruta montada (/data), no en /app/data del layer efímero si no coincide con el mount.
Offsite recomendado: template postgres-s3-backups adaptado a sqlite, o cron dentro del contenedor que sube a R2. Los backups nativos son capa cómoda, no capa única.
SQLite: copia consistente
Copiar agent.db con cp mientras hay escrituras puede dejarte un archivo corrupto. SQLite documenta la API Online Backup y el comando CLI .backup:
sqlite3 /data/agent.db ".backup '/backup/agent-$(date +%F).db'"
Con WAL activado, un file copy puede ser seguro si el proceso hace checkpoint — pero .backup es el camino documentado. Para producción seria, Litestream replica WAL a S3 en tiempo real (mención como patrón, no como fuente primaria del post).
Ensayo: restaura el .backup en Preview y confirma que el agente recuerda una sesión de prueba.
Docker en VPS
Del tutorial Docker:
docker run --rm \
-v agente_data:/data \
-v $PWD/backups:/backup \
alpine sh -c 'sqlite3 /data/agent.db ".backup /backup/agent-$(date +%F).db"'
O tarball del volumen nombrado:
docker run --rm -v agente_data:/data -v $PWD:/backup alpine \
tar czf /backup/agente-data-$(date +%F).tgz -C /data .
Programa en cron del host (no dentro del contenedor que puede morir). Retención: 7 diarios + 4 semanales; copia una semanal offsite.
Restore: para el compose, restaura el archivo, docker compose up -d, verifica healthcheck.
Fly.io: volúmenes regionales
Fly monta volúmenes en una región — no migran solos entre regiones. Backup vía:
- Snapshot de la plataforma (según plan y tooling Fly).
fly ssh console+.backupsqlite a un almacenamiento externo.- Replicar estado en DB gestionada si necesitas multi-región.
Restore en Fly suele ser: nuevo volumen + copiar datos + remount — planifícalo antes del incidente. Un rollback de código no monta el volumen viejo automáticamente.
Flujo de restore sin incidente mayor

- Detecta corrupción o borrado (usuario, bug, deploy).
- Para escrituras — modo mantenimiento o apaga webhook (Telegram sin webhook = agente mudo).
- Elige backup — el anterior al deploy sospechoso, no el más reciente si el bug ya escribió basura.
- Restore en staging primero si tienes environment separado.
- Remonta volumen o swap archivo sqlite.
- Health 200 → reabre webhook → monitor alertas.
Railway restore nativo reemplaza el contenido del volumen en el mismo environment — hazlo con el servicio detenido o en ventana de mantenimiento.
Errores comunes

| Error | Consecuencia | Fix |
|---|---|---|
| Estado en filesystem efímero del contenedor | Se pierde en cada deploy | Volumen en /data |
| Solo backup nativo Railway | volume delete = adiós | Offsite semanal |
| Restore el backup más nuevo | Reintroduces el bug que corrompió datos | Backup anterior al incidente |
cp sqlite con tráfico | Archivo corrupto | .backup o Litestream |
| Backup incluye PII sin cifrar | Incidente de privacidad | Cifrar bucket; minimizar datos |
Relación con rollback
| Acción | Qué revierte |
|---|---|
| Rollback de deploy | Código e imagen |
| Restore de volumen | Archivos en disco |
| Rotación de secretos | Llaves comprometidas |
Los tres son ortogonales. Un deploy malo + sqlite sano → rollback. Un bug que escribió mal la DB → restore de backup, no rollback.
Checklist
- Estado del agente en volumen persistente (no layer efímero)
- Backup nativo programado (Railway daily o cron Docker)
- Copia offsite ≥ semanal (S3/R2/Bucket)
- Restore ensayado en staging este mes
- Runbook: quién aprueba restore y cómo apagar webhook
- Retención definida (cuántos días de conversaciones guardas)
Un agente sin backup de estado es un chatbot con amnesia selectiva: funciona hasta el día que no.
Siguiente paso: cablea alertas para saber que el servicio murió y logs para saber por qué. Si el estado aún no existe porque no desplegaste, el curso gratuito deja un sqlite local para practicar .backup antes de subirlo.
Lecturas relacionadas
Sigue explorando Deploy y otras piezas para builders.



