Los contenedores son efímeros por naturaleza: cuando se eliminan, todo lo que escribieron en su sistema de archivos interno desaparece. En esta lección profundizaremos en las distintas opciones que ofrece Docker para gestionar datos de forma persistente y eficiente: volúmenes, bind mounts y tmpfs. Además, entenderemos cómo funcionan los storage drivers como overlay2, cómo gestionar el ciclo de vida de los volúmenes y cómo realizar copias de seguridad y restauraciones. Elegir bien la opción de almacenamiento es clave para la fiabilidad y el rendimiento de tus aplicaciones.
Las Tres Opciones de Almacenamiento
Docker ofrece tres mecanismos principales para que los datos sobrevivan más allá del sistema de archivos del contenedor o para optimizar el rendimiento.
| Característica | Volúmenes | Bind Mounts | tmpfs |
|---|---|---|---|
| Gestionado por Docker | Sí | No (lo gestiona el usuario) | Sí |
| Ubicación | Área controlada por Docker | Cualquier ruta del host | Memoria RAM del host |
| Persistencia tras reinicio | Sí | Sí | No (se borra al detener el contenedor) |
| Portabilidad | Alta | Baja (depende de rutas del host) | No persiste |
| Caso de uso típico | Bases de datos, datos de aplicación | Desarrollo, ficheros de configuración | Datos sensibles temporales, cachés |
| Funciona en Windows/Linux | Sí | Sí (con matices de rutas) | Solo Linux |
Volúmenes
Son la opción recomendada por Docker para la mayoría de casos. Docker los almacena en un área gestionada (en Linux, /var/lib/docker/volumes/) y se manipulan exclusivamente con comandos de Docker.
docker volume create datos_app: crea un volumen nombrado.-v datos_app:/app/data: monta el volumen en/app/datadentro del contenedor.
Bind Mounts
Montan una ruta concreta del host dentro del contenedor. Útiles en desarrollo para reflejar cambios de código en tiempo real, pero menos portables porque dependen de la estructura del host.
/home/usuario/sitio:/usr/share/nginx/html: la ruta de la izquierda es del host; la de la derecha, del contenedor. Cualquier cambio en el host se ve inmediatamente en el contenedor.
La sintaxis moderna con --mount es más explícita y recomendada:
docker run -d --name web \
--mount type=bind,source=/home/usuario/sitio,target=/usr/share/nginx/html \
nginxtype=bind: indica que es un bind mount.source: ruta en el host.target: ruta en el contenedor.
tmpfs
Almacena datos en la memoria RAM del host. No persisten, pero son muy rápidos y nunca se escriben en disco, lo que es ideal para datos sensibles temporales.
--tmpfs /app/temporal: crea un sistema de archivos en memoria montado en/app/temporal.rw,size=64m: lectura/escritura con un límite de 64 MB.
Storage Drivers: overlay2
Mientras que las opciones anteriores gestionan datos persistentes, el storage driver gobierna cómo Docker construye y gestiona las capas de las imágenes y la capa de escritura de los contenedores.
overlay2 es el driver por defecto y recomendado en las distribuciones Linux modernas. Funciona con un sistema de archivos de unión (union filesystem) que superpone varias capas de solo lectura (las de la imagen) y una capa superior de escritura (la del contenedor).
- Devuelve, por ejemplo,
overlay2.
Conceptos clave de overlay2:
- lowerdir: capas de solo lectura de la imagen.
- upperdir: capa de escritura del contenedor (todo cambio se escribe aquí).
- Copy-on-Write (CoW): cuando un contenedor modifica un fichero existente de la imagen, Docker copia ese fichero a la capa de escritura antes de modificarlo, dejando intacta la imagen original.
El CoW explica por qué los contenedores arrancan rápido y ocupan poco: comparten las capas de solo lectura y solo escriben sus diferencias.
Gestión del Ciclo de Vida de los Volúmenes
Conocer los comandos para administrar volúmenes te ayuda a mantener el sistema limpio y bajo control.
# Listar volúmenes
docker volume ls
# Inspeccionar un volumen (ruta real, driver, etiquetas)
docker volume inspect datos_app
# Eliminar un volumen concreto
docker volume rm datos_app
# Eliminar todos los volúmenes sin usar
docker volume prunedocker volume inspect: muestra el campoMountpoint, que es la ruta real en el host.docker volume prune: libera espacio eliminando volúmenes huérfanos. Úsalo con cuidado: borra datos no asociados a ningún contenedor.
Volúmenes Nombrados y Anónimos
| Tipo | Cómo se crea | Identificación | Ciclo de vida |
|---|---|---|---|
| Nombrado | docker volume create nombre o -v nombre:/ruta |
Nombre legible | Persiste hasta que lo borras |
| Anónimo | -v /ruta (sin nombre antes de los dos puntos) |
Hash aleatorio largo | Se puede borrar con docker rm -v |
Volumen nombrado
datos_dbes reconocible y reutilizable por otros contenedores.
Volumen anónimo
- Al no indicar nombre, Docker genera uno aleatorio (un hash largo). Son difíciles de identificar después, por lo que es preferible usar volúmenes nombrados para datos importantes.
-v: borra también los volúmenes anónimos asociados, evitando que queden huérfanos.
Copias de Seguridad y Restauración de Volúmenes
Los volúmenes contienen datos valiosos, por lo que conviene saber respaldarlos. La técnica estándar consiste en lanzar un contenedor auxiliar que monte el volumen y un directorio del host, y comprimir el contenido.
Copia de seguridad
docker run --rm \
-v datos_db:/datos \
-v $(pwd):/backup \
alpine \
tar czf /backup/backup_datos_db.tar.gz -C /datos .--rm: elimina el contenedor auxiliar al terminar.-v datos_db:/datos: monta el volumen a respaldar como solo origen.-v $(pwd):/backup: monta el directorio actual del host para guardar el resultado.tar czf ... -C /datos .: crea un archivo comprimido del contenido del volumen.
En PowerShell de Windows, sustituye $(pwd) por ${PWD}.
Restauración
docker run --rm \
-v datos_db_nuevo:/datos \
-v $(pwd):/backup \
alpine \
sh -c "tar xzf /backup/backup_datos_db.tar.gz -C /datos"- Crea (o reutiliza) un volumen
datos_db_nuevoy extrae en él el contenido del archivo de respaldo. sh -c "...": ejecuta el comando de extracción dentro de una shell.
Cuándo Usar Cada Opción
- Volúmenes: por defecto, siempre que necesites persistencia gestionada y portable (bases de datos, datos de aplicación, datos compartidos entre contenedores).
- Bind mounts: en desarrollo, cuando quieras editar código en el host y verlo reflejado al instante, o para inyectar ficheros de configuración concretos.
- tmpfs: para datos temporales sensibles (tokens, secretos en memoria) o cachés de alto rendimiento que no deben tocar el disco.
Errores Comunes y Consejos
- Confundir el orden host:contenedor: en
-v origen:destino, el origen es siempre el host (o el nombre del volumen) y el destino es el contenedor. Invertirlo provoca comportamientos inesperados. - Usar bind mounts en producción: dependen de rutas del host concretas y rompen la portabilidad. Prefiere volúmenes.
- Olvidar
-val eliminar contenedores: los volúmenes anónimos se acumulan como basura. Usadocker rm -vo revisa condocker volume ls. - Borrar volúmenes con datos por descuido:
docker volume pruneydocker volume rmson destructivos. Haz copias de seguridad antes. - Permisos en bind mounts: el usuario del contenedor puede no tener permisos sobre la ruta del host. Ajusta propietarios/permisos si surgen errores de acceso.
- Consejo: documenta en tu
docker-compose.ymlqué volumen guarda qué, para que el equipo entienda dónde viven los datos críticos.
Ejercicios
Ejercicio 1: Persistencia con volumen nombrado
Lanza un contenedor PostgreSQL con un volumen nombrado, crea una base de datos, elimina el contenedor y vuelve a lanzarlo reutilizando el mismo volumen. Comprueba que la base de datos sigue ahí.
Ejercicio 2: Copia de seguridad y restauración
Crea un volumen con un fichero de prueba dentro, realiza una copia de seguridad en formato .tar.gz, borra el volumen original y restaura el contenido en un volumen nuevo.
Ejercicio 3: tmpfs para datos temporales
Lanza un contenedor con un montaje tmpfs limitado a 32 MB, escribe un fichero en él, detén y reinicia el contenedor y comprueba que el fichero ya no existe.
Soluciones
Solución 1
docker volume create datos_pg
docker run -d --name pg -e POSTGRES_PASSWORD=ejemplo -v datos_pg:/var/lib/postgresql/data postgres:16
docker exec -it pg psql -U postgres -c "CREATE DATABASE prueba;"
docker rm -f pg
docker run -d --name pg -e POSTGRES_PASSWORD=ejemplo -v datos_pg:/var/lib/postgresql/data postgres:16
docker exec -it pg psql -U postgres -c "\l" # 'prueba' debe seguir apareciendoSolución 2
docker volume create origen
docker run --rm -v origen:/datos alpine sh -c "echo 'contenido de prueba' > /datos/fichero.txt"
# Copia de seguridad
docker run --rm -v origen:/datos -v $(pwd):/backup alpine tar czf /backup/copia.tar.gz -C /datos .
# Borrar el original y restaurar en uno nuevo
docker volume rm origen
docker volume create destino
docker run --rm -v destino:/datos -v $(pwd):/backup alpine sh -c "tar xzf /backup/copia.tar.gz -C /datos"
docker run --rm -v destino:/datos alpine cat /datos/fichero.txt # Muestra 'contenido de prueba'Solución 3
docker run -d --name temporal --tmpfs /datos:rw,size=32m alpine sleep 3600
docker exec -it temporal sh -c "echo hola > /datos/efimero.txt && cat /datos/efimero.txt"
docker restart temporal
docker exec -it temporal ls /datos # El fichero ya no existe: tmpfs vive en RAMConclusión
En esta lección hemos comparado en profundidad las tres opciones de almacenamiento de Docker (volúmenes, bind mounts y tmpfs), hemos entendido cómo el storage driver overlay2 gestiona las capas mediante Copy-on-Write, hemos repasado el ciclo de vida de los volúmenes y hemos aprendido a respaldar y restaurar datos. Saber elegir y administrar el almacenamiento correcto garantiza que tus datos sean fiables, portables y eficientes.
En la siguiente lección, Mejores Prácticas de Seguridad en Docker, abordaremos cómo proteger tus contenedores: ejecutar como usuario no privilegiado, usar imágenes base mínimas, escanear vulnerabilidades, gestionar secretos y aplicar el principio de mínimo privilegio.
Docker: De Principiante a Avanzado
Módulo 1: Introducción a Docker
- ¿Qué es Docker?
- Instalando Docker
- Arquitectura de Docker
- Comandos Básicos de Docker
- Entendiendo las Imágenes de Docker
- Creando tu Primer Contenedor Docker
Módulo 2: Trabajando con Imágenes Docker
- Docker Hub y Repositorios
- Construyendo Imágenes Docker
- Conceptos Básicos de Dockerfile
- Gestionando Imágenes Docker
- Etiquetado y Publicación de Imágenes
Módulo 3: Contenedores Docker
- Ejecutando Contenedores
- Ciclo de Vida del Contenedor
- Gestionando Contenedores
- Redes en Docker
- Persistencia de Datos con Volúmenes
Módulo 4: Docker Compose
- Introducción a Docker Compose
- Definiendo Servicios en Docker Compose
- Comandos de Docker Compose
- Aplicaciones Multi-Contenedor
- Variables de Entorno en Docker Compose
Módulo 5: Conceptos Avanzados de Docker
- Profundización en Redes Docker
- Opciones de Almacenamiento Docker
- Mejores Prácticas de Seguridad en Docker
- Optimizando Imágenes Docker
- Registro y Monitoreo en Docker
Módulo 6: Docker en Producción
- CI/CD con Docker
- Orquestando Contenedores con Docker Swarm
- Introducción a Kubernetes
- Desplegando Contenedores Docker en Kubernetes
- Escalado y Balanceo de Carga
