Volúmenes y datos en Docker

Aprende Docker → Lección 7

Un contenedor es efímero por diseño: lo que escribe dentro desaparece cuando se elimina, y eliminarlo es exactamente lo que ocurre en cada despliegue. Esta lección va de decidir qué datos tienen que sobrevivir a eso y cómo se consigue.

Lo que pasa sin volumen

Dos contenedores de la misma imagen no comparten nada de lo que escriban:

docker run --rm alpine:3.22 sh -c 'echo "dato importante" > /datos.txt && cat /datos.txt'
docker run --rm alpine:3.22 sh -c 'cat /datos.txt 2>/dev/null || echo "el archivo ya no existe"'
salidadato importante
el archivo ya no existe: se fue con el contenedor

El archivo se escribió en la capa escribible del primer contenedor y murió con él. Para una aplicación sin estado eso está bien y es deseable. Para una base de datos sería una catástrofe.

Volúmenes con nombre: la opción por defecto

Un volumen es almacenamiento que Docker gestiona, independiente del ciclo de vida de los contenedores:

docker volume create datos-app
docker run --rm -v datos-app:/datos alpine:3.22 sh -c 'echo "dato importante" > /datos/archivo.txt'
docker run --rm -v datos-app:/datos alpine:3.22 sh -c 'cat /datos/archivo.txt'
salidadato importante

El segundo contenedor es distinto del primero y aun así lee lo que el otro dejó. Esta es la forma correcta para datos de producción: bases de datos, archivos subidos por usuarios, cualquier cosa que no deba perderse al desplegar.

Montar una carpeta de tu máquina

Un montaje de enlace conecta una carpeta real del anfitrión con una ruta del contenedor. Se usa sobre todo en desarrollo, para editar código fuera y verlo dentro sin reconstruir:

docker run --rm -v "$PWD/compartida:/montada:ro" alpine:3.22 cat /montada/nota.txt
salidaeditado desde fuera

Ese :ro del final lo monta de solo lectura. Si el contenedor intenta escribir:

intentando escribir en un montaje :rosh: can't create /montada/nuevo.txt: Read-only file system
Monta de solo lectura siempre que puedas. Un montaje de enlace da al contenedor acceso real a tu disco: si el proceso de dentro borra algo, lo borra de verdad en tu máquina. Añadir :ro cuesta tres caracteres y elimina esa clase entera de accidentes. Solo quita el :ro cuando el contenedor tenga que escribir de verdad.

Cuál usar

CasoQué usar
Datos de una base de datosVolumen con nombre
Archivos subidos por usuariosVolumen con nombre, o almacenamiento externo
Código fuente mientras desarrollasMontaje de enlace
Un archivo de configuración del anfitriónMontaje de enlace con :ro
Caché o archivos temporalesNada: que se pierdan está bien
Datos compartidos entre varios contenedoresUn volumen con nombre montado en todos

Órdenes útiles

Qué quieresOrden
Listar los volúmenesdocker volume ls
Ver dónde está uno en el discodocker volume inspect nombre
Eliminar unodocker volume rm nombre
Ver cuánto ocupandocker system df -v
Copiar datos fuera para respaldodocker run --rm -v vol:/d -v $PWD:/copia alpine tar czf /copia/copia.tgz /d
Un volumen no es una copia de seguridad. Sobrevive a los contenedores, pero vive en el mismo disco de la misma máquina: si el servidor se pierde, se pierde con él. Y docker compose down -v borra los volúmenes del proyecto sin preguntar, que es una forma rápida y silenciosa de perder una base de datos de desarrollo con datos que costó rellenar. Para datos que importen, respaldo aparte.