Volumes y persistencia en Docker | Nicolás Garzón
Texto
Copiar container reemplazable
↓ mount
named volume persistente
↓
filesystem del host administrado por DockerEsta separación evita depender de la writable layer, pero no convierte los datos en altamente disponibles, respaldados o seguros. Un volume sigue perteneciendo a una infraestructura concreta y necesita ownership, capacidad, backup, restore y migración.
Bash
Copiar docker volume create postgres-data
docker run -d \
--name db \
--mount type = volume,src= postgres-data,dst= /var/lib/postgresql/data \
postgres:17Bash
Copiar docker volume inspect postgres-data
docker inspect db --format '{{json .Mounts}}' La ruta destino debe coincidir con el directorio de datos soportado por la aplicación. Montar una ruta equivocada puede dar la ilusión de persistencia mientras la database escribe en otro lugar.
El volume permanece conectado y sus datos siguen existiendo.
El named volume permanece normalmente:
Bash
Copiar docker rm -f db
docker volume ls Puede conectarse a una nueva instancia:
Bash
Copiar docker run -d \
--name db-new \
--mount type = volume,src= postgres-data,dst= /var/lib/postgresql/data \
postgres:17Bash
Copiar docker volume rm postgres-dataLa eliminación puede ser irreversible. Docker impide algunos borrados mientras existe una referencia activa, pero “no conectado” no significa “sin datos importantes”.
Bash
Copiar docker volume create app-data
nombre estable;
fácil de inspeccionar;
puede etiquetarse;
puede reutilizarse conscientemente;
facilita políticas de backup y retención.
Bash
Copiar docker run --mount type = volume,dst= /data my-appDocker genera una identidad. Puede ser apropiado para datos temporales asociados a una instancia, pero suele acumularse y ser difícil de relacionar con un servicio.
--rm puede eliminar ciertos anonymous volumes asociados, pero no confíes en ello como estrategia de administración sin probar el flujo exacto.
docker
Copiar VOLUME ["/data"]Puede provocar creación de volumes anónimos y trasladar decisiones de lifecycle al consumidor de forma poco explícita. En aplicaciones propias suele ser más claro declarar persistencia en Compose o runtime.
crear un backup;
reservar capacidad;
replicar datos;
cifrar contenido;
compartirlo entre hosts.
Si la imagen tiene archivos en el destino y se monta un volume vacío, Docker puede copiar contenido inicial al volume en escenarios soportados.
Esto es útil para defaults, pero peligroso como sistema de migrations:
solo ocurre cuando el volume está vacío;
una segunda versión no actualiza automáticamente archivos existentes;
puede ocultar contenido inferior de la image;
el comportamiento debe probarse con el tipo de mount y versión.
Las migrations deben ser explícitas, versionadas, idempotentes cuando corresponda y observables.
El proceso utiliza UID/GID dentro del contenedor. El storage conserva ownership numérico.
Texto
Copiar volume creado/escrito como root
→ nueva image ejecuta UID 10001
→ permission deniedBash
Copiar docker run --rm \
--mount type = volume,src= app-data,dst= /data \
alpine ls -ln /data
crear directorios y ownership durante inicialización controlada;
usar COPY --chown para contenido de image;
ejecutar un init job con privilegios mínimos;
fijar UID/GID coherentes;
configurar opciones del driver o plataforma.
Evita chmod -R 777: oculta el diseño de permisos y amplía acceso.
En rootless mode o con user namespace remapping, los IDs del contenedor se mapean a IDs no privilegiados del host. Esto reduce impacto, pero puede complicar ownership de almacenamiento existente.
creación;
lectura/escritura;
backup;
restore;
migración entre hosts;
downgrade.
Un volume puede crecer hasta consumir el filesystem subyacente si no existe cuota.
Bash
Copiar docker system df -v
df -h
df -i
tamaño por servicio;
crecimiento diario;
inodes;
latencia de disco;
errores de I/O;
espacio requerido para compaction, upgrades y restore.
Una database puede necesitar espacio temporal adicional durante vacuum, index rebuild o upgrade. No dimensionar solo con el tamaño actual.
El driver local es común en un solo host. Otros drivers o plugins pueden conectar almacenamiento externo.
Un driver distinto cambia:
disponibilidad;
rendimiento;
autenticación;
opciones de mount;
consistencia;
soporte de snapshots;
portabilidad;
comportamiento ante pérdida de red.
No asumas que un volume con nombre idéntico en dos hosts contiene los mismos datos. Con driver local son recursos separados.
Persistencia significa que los datos sobreviven al contenedor. Backup significa tener una copia recuperable frente a:
eliminación accidental;
corrupción;
ransomware;
fallo de host o disco;
bug de aplicación;
upgrade defectuoso;
pérdida de credenciales.
Una copia en el mismo disco no protege frente a pérdida del host.
Puede copiarse contenido con el servicio detenido o mediante mecanismos de snapshot consistentes.
No copies arbitrariamente archivos activos. Usa:
dumps lógicos;
herramientas nativas;
base backups;
snapshots coordinados;
replication según motor.
La consistencia depende del sistema, no de Docker.
Ejemplo simple de archive para datos no activos:
Bash
Copiar docker run --rm \
--mount type = volume,src= app-data,dst= /data,readonly \
--mount type = bind,src= "$PWD /backups" ,dst= /backup \
alpine tar -czf /backup/app-data.tar.gz -C /data . Esto no garantiza consistencia de una database en ejecución.
Un backup solo se considera válido después de restaurarlo y verificarlo.
crear un volume nuevo;
restaurar datos;
iniciar una instancia aislada;
ejecutar validaciones funcionales;
medir tiempo de recuperación;
documentar dependencias y versiones;
conservar evidencia.
Ejemplo de restore para archivos:
Bash
Copiar docker volume create app-data-restore
docker run --rm \
--mount type = volume,src= app-data-restore,dst= /data \
--mount type = bind,src= "$PWD /backups" ,dst= /backup,readonly \
alpine tar -xzf /backup/app-data.tar.gz -C /dataAl cambiar la image de una database, el mismo volume contiene formato de datos de la versión anterior.
Texto
Copiar postgres:14 → postgres:17sin procedimiento soportado. Puede requerir dump/restore, herramientas de upgrade, réplica o pasos intermedios.
lee compatibilidad;
crea backup verificable;
prueba con copia;
mide downtime;
define rollback;
considera que el formato puede dejar de ser downgrade-compatible.
Bash
Copiar docker run \
--mount type = volume,src= config-data,dst= /app/config,readonly \
my-appÚtil para consumidores que no deben modificar contenido.
Read-only en el mount no impide que otro container con acceso writable cambie los datos. Controla quién puede conectarlo.
productor/consumidor estrechamente coordinado;
archivos generados;
sidecar de backup;
sockets locales.
escrituras concurrentes;
locking no soportado;
ownership incompatible;
acoplamiento fuerte;
corrupción;
lifecycle confuso.
Una database no debe escalarse simplemente montando el mismo filesystem en varias instancias salvo que el motor y storage soporten explícitamente ese modelo.
YAML
Copiar services :
db :
image : postgres: 17
volumes :
- db- data: /var/lib/postgresql/data
volumes :
db-data :
labels :
com.nicoo.purpose : databasedocker compose down conserva named volumes. docker compose down -v los elimina. La diferencia es crítica.
YAML
Copiar volumes :
db-data :
external : true Compose no administra su creación/eliminación; el recurso debe existir.
Una API guarda uploads en /app/uploads.
Un named volume puede ser suficiente:
YAML
Copiar volumes :
- uploads: /app/uploadsUn volume local produce datos diferentes por host. Considera object storage o almacenamiento compartido apropiado.
consistencia;
disponibilidad;
tamaño;
latencia;
acceso público;
backups;
escalado.
Bash
Copiar docker inspect container --format '{{json .Mounts}}'
docker volume ls
docker volume inspect volume-name
¿la app escribió en la ruta montada?
¿se recreó con otro nombre de volume?
¿Compose cambió project name?
¿se ejecutó down -v o prune?
¿el mount ocultó otro contenido?
Revisa UID/GID, modo, rootless mapping y ownership real.
Puede ser otro volume con nombre parecido o generado por un project name distinto.
Revisa datos, logs, images y build cache. No elimines volumes al azar.
No está conectado, pero contiene la última copia de datos.
La aplicación nueva no puede leer el formato. Conserva metadata de versión junto al backup.
Cifra, controla acceso y define retención.
Puede provocar corrupción silenciosa.
El volume vive dentro del entorno Linux administrado, no como un directorio fácil de manipular desde macOS/Windows.
Corrección: copia externa y restore probado.
Corrección: nombres, labels e inventario.
Corrección: procedimiento soportado y prueba.
Corrección: topología nativa del motor.
Corrección: ownership, labels, backups y aprobación.
Un volume sobrevive al container, no necesariamente al host.
Persistencia no equivale a backup ni alta disponibilidad.
Named volumes son más administrables que anonymous volumes.
Ownership numérico importa.
Backups deben ser consistentes con la aplicación y restaurables.
Un upgrade de image puede requerir migración de datos.
Comprueba lo aprendido
¿Qué diferencias existen entre restart, recreate y pérdida del host para un volume local?
Diseña backup y restore para una database en container.
¿Por qué un volume con el mismo nombre en dos hosts no implica datos compartidos?
¿Cómo diagnosticarías un volume que parece vacío después de Compose?
¿Cuándo elegirías object storage en lugar de un named volume?
Bind mounts y tmpfs , donde el container cruza explícitamente la frontera del filesystem del host o utiliza almacenamiento temporal en memoria.