Backup failed: Volume path does not exist: 7fe348ca-4f53-4257-a318-ef9fedc68374Este error cuenta toda la historia en una línea. El motor de respaldos recibió un UUID como "ruta de volumen" e intentó abrirlo como un directorio del filesystem. Incluso si hubiera recibido la ruta correcta (/var/lib/postgresql/data), igual habría fallado. Esa ruta existe dentro del contenedor Docker, no en el host.
El enfoque correcto es nunca tocar el filesystem del host. Usa la propia API de Docker para copiar archivos fuera de contenedores.
Por qué exec + tar también falla
El primer instinto fue usar docker exec para ejecutar tar dentro del contenedor. Esto falla por una razón diferente. La API exec de Docker devuelve un stream multiplexado donde stdout y stderr se intercalan con encabezados de frame de 8 bytes. Nuestro parser de stream convierte frames stdout a un String de Rust vía str::from_utf8. Un archivo tar es datos binarios. Los datos binarios no son UTF-8 válido. La llamada from_utf8 silenciosamente omite frames con contenido binario, produciendo un archivo corrupto.
La API de archivos de Docker
Docker tiene una API construida a propósito para copiar archivos dentro y fuera de contenedores:
GET /containers/{id}/archive?path=/path-- Devuelve un archivo tar de la ruta especificadaPUT /containers/{id}/archive?path=/path-- Sube un archivo tar y lo extrae en la ruta especificada
Estos endpoints manejan datos binarios correctamente (el cuerpo de respuesta son bytes crudos, no un stream multiplexado), soportan cualquier tipo de archivo, y funcionan independientemente de qué herramientas estén instaladas dentro del contenedor.
Agregamos dos métodos al cliente Docker: copy_from_container y copy_to_container.
El pipeline de respaldo después de la corrección
El motor ahora usa copy_from_container para respaldos de volumen. Los datos devueltos ya son un archivo tar. El pipeline luego comprime (gzip), opcionalmente encripta (AES-256-GCM), y almacena vía el proveedor de almacenamiento configurado. En la restauración, el proceso se invierte.
La lección: usa la API de la plataforma
Todo runtime de contenedores proporciona APIs para movimiento de datos. Docker tiene archive. Podman tiene los mismos endpoints. Kubernetes tiene kubectl cp. Usar exec + comandos de shell es tentador porque se siente familiar, pero introduce dependencias, problemas de codificación, y problemas de permisos.
La API de la plataforma maneja todo esto. Funciona con cada imagen, cada filesystem, cada codificación. Cuando muevas datos dentro o fuera de contenedores, siempre prefiere la API nativa de movimiento de datos de la plataforma sobre soluciones basadas en exec.