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

Caso Qué usar
Datos de una base de datos Volumen con nombre
Archivos subidos por usuarios Volumen con nombre, o almacenamiento externo
Código fuente mientras desarrollas Montaje de enlace
Un archivo de configuración del anfitrión Montaje de enlace con :ro
Caché o archivos temporales Nada: que se pierdan está bien
Datos compartidos entre varios contenedores Un volumen con nombre montado en todos

Órdenes útiles

Qué quieres Orden
Listar los volúmenes docker volume ls
Ver dónde está uno en el disco docker volume inspect nombre
Eliminar uno docker volume rm nombre
Ver cuánto ocupan docker system df -v
Copiar datos fuera para respaldo docker 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.