Hay un detalle de los contenedores que sorprende a casi todos los principiantes: cuando eliminas un contenedor, todos los datos que había dentro desaparecen para siempre. Esto está muy bien para procesos temporales, pero es un problema serio si tienes una base de datos o cualquier información que debas conservar. La solución son los volúmenes, el mecanismo que ofrece Docker para que los datos sobrevivan más allá de la vida del contenedor. En esta lección introductoria entenderás por qué se pierden los datos, conocerás las dos formas básicas de persistirlos (volúmenes y bind mounts), aprenderás los comandos esenciales para gestionar volúmenes y verás un ejemplo real con una base de datos.
¿Por Qué se Pierden los Datos?
Cada contenedor tiene su propio sistema de archivos, construido a partir de la imagen más una capa de escritura propia. Esa capa de escritura está atada a la vida del contenedor: existe mientras existe el contenedor y se destruye con él.
# Crear un contenedor y escribir un fichero dentro
docker run -it --name prueba alpine sh
# Dentro del contenedor:
echo "datos importantes" > /datos.txt
exit
# Eliminar el contenedor
docker rm prueba- Cuando ejecutas
docker rm prueba, el fichero/datos.txtdesaparece junto con el contenedor. - Si vuelves a crear un contenedor a partir de la misma imagen, no encontrarás ese fichero: cada contenedor parte de cero.
Este comportamiento se llama naturaleza efímera de los contenedores. Para guardar datos de forma duradera, necesitamos almacenarlos fuera de la capa de escritura del contenedor. Ahí entran los volúmenes y los bind mounts.
Volúmenes vs. Bind Mounts
Docker ofrece dos formas básicas de persistir datos fuera del contenedor. A nivel introductorio, estas son las que necesitas conocer.
| Característica | Volúmenes | Bind Mounts |
|---|---|---|
| Quién los gestiona | Docker | Tú (el usuario) |
| Dónde se guardan | En un área controlada por Docker | En una ruta concreta de tu host |
| Facilidad de uso | Alta (Docker se encarga de todo) | Media (debes indicar la ruta exacta) |
| Portabilidad | Alta | Baja (depende de tu máquina) |
| Caso de uso típico | Bases de datos, datos de aplicación | Desarrollo, compartir código o config |
Volúmenes
Son la opción recomendada para la mayoría de los casos. Docker los almacena en un lugar que él gestiona, y tú solo tienes que darles un nombre. No necesitas saber dónde están físicamente: Docker se ocupa.
Bind Mounts
Un bind mount conecta una carpeta concreta de tu ordenador con una carpeta dentro del contenedor. Es muy útil en desarrollo (por ejemplo, para editar código en tu host y verlo reflejado al instante), pero menos portable porque depende de las rutas de tu máquina.
- A la izquierda de los dos puntos va la ruta de tu host; a la derecha, la del contenedor.
- Cualquier cambio en la carpeta del host se ve inmediatamente dentro del contenedor.
En esta lección nos centraremos sobre todo en los volúmenes, por ser la opción más sencilla y recomendada para empezar.
Gestionar Volúmenes con Comandos
Docker incluye un conjunto de comandos claros para administrar volúmenes.
Crear un volumen
docker volume create: crea un volumen nuevo.datos_app: el nombre que le damos. Lo usaremos después para montarlo en un contenedor.
Listar volúmenes
- Muestra todos los volúmenes existentes en tu sistema, con su driver y su nombre.
Inspeccionar un volumen
- Muestra los detalles del volumen, incluida la ruta real donde Docker guarda los datos (campo
Mountpoint).
Eliminar un volumen
- Elimina el volumen indicado. Atención: esto borra los datos que contiene de forma permanente.
- Solo se puede eliminar un volumen si ningún contenedor lo está usando.
Montar un Volumen en un Contenedor
Para que un contenedor use un volumen, lo "montamos" en una ruta interna con el flag -v.
-v datos_app:/app/data: monta el volumendatos_appen la carpeta/app/datadentro del contenedor.- La sintaxis es
nombre_volumen:ruta_en_el_contenedor. - Todo lo que la aplicación escriba en
/app/datase guardará en el volumen, y por tanto sobrevivirá aunque elimines el contenedor.
Si el volumen no existe todavía, Docker lo crea automáticamente al lanzar el contenedor. Aun así, crearlo antes con docker volume create es buena práctica para tener control.
Ejemplo Práctico: Base de Datos con Datos Persistentes
Veamos el caso que mejor ilustra la utilidad de los volúmenes: una base de datos cuyos datos deben sobrevivir a la recreación del contenedor.
Paso 1: crear el volumen y lanzar la base de datos
docker volume create datos_pg
docker run -d --name basedatos \
-e POSTGRES_PASSWORD=ejemplo \
-v datos_pg:/var/lib/postgresql/data \
postgres:16docker volume create datos_pg: creamos el volumen donde vivirán los datos.-e POSTGRES_PASSWORD=ejemplo: contraseña del administrador (dato ficticio).-v datos_pg:/var/lib/postgresql/data: montamos el volumen en la carpeta donde PostgreSQL guarda sus datos. Esta ruta interna es la que usa PostgreSQL por defecto.
Paso 2: crear datos dentro de la base de datos
docker exec -it basedatos: entramos en el contenedor en ejecución.psql -U postgres -c "CREATE DATABASE tienda;": creamos una base de datos llamadatienda.
Paso 3: eliminar el contenedor
docker rm -f: detiene y elimina el contenedor. ¡Pero los datos están a salvo en el volumen!
Paso 4: recrear el contenedor reutilizando el volumen
docker run -d --name basedatos \
-e POSTGRES_PASSWORD=ejemplo \
-v datos_pg:/var/lib/postgresql/data \
postgres:16
# Comprobar que la base de datos 'tienda' sigue existiendo
docker exec -it basedatos psql -U postgres -c "\l"- Volvemos a lanzar un contenedor nuevo, montando el mismo volumen
datos_pg. psql -U postgres -c "\l": lista las bases de datos. Verás quetiendasigue ahí.- Esto demuestra el poder de los volúmenes: el contenedor es nuevo, pero los datos persisten.
Errores Comunes y Consejos
- Olvidar el volumen en bases de datos: si lanzas PostgreSQL sin un volumen y eliminas el contenedor, pierdes todos los datos. Monta siempre un volumen para datos importantes.
- Invertir el orden en
-v: la sintaxis esvolumen:contenedor. El primer elemento es el nombre del volumen (o ruta del host), el segundo es la ruta dentro del contenedor. - Borrar volúmenes sin querer:
docker volume rmelimina los datos para siempre. Asegúrate antes de que no los necesitas. - Confundir volúmenes con bind mounts: si necesitas portabilidad y que Docker lo gestione, usa volúmenes; si quieres conectar una carpeta concreta de tu host, usa bind mounts.
- Suponer que el volumen guarda toda la aplicación: el volumen solo persiste la carpeta donde lo montas, no todo el contenedor.
- Consejo: usa nombres de volúmenes descriptivos (
datos_pg,archivos_web) para saber de un vistazo qué contiene cada uno.
Ejercicios
Ejercicio 1: comprobar la pérdida de datos
Crea un contenedor de Alpine sin volumen, escribe un fichero dentro, elimina el contenedor y crea otro nuevo. Comprueba que el fichero ha desaparecido.
Ejercicio 2: gestionar un volumen
Crea un volumen, lístalo, inspecciónalo para ver dónde guarda Docker los datos y, por último, elimínalo.
Ejercicio 3: persistencia real
Lanza un contenedor de PostgreSQL con un volumen, crea una base de datos, elimina el contenedor y vuelve a lanzarlo reutilizando el mismo volumen. Verifica que la base de datos sigue existiendo.
Soluciones
Solución 1
docker run -it --name sin_volumen alpine sh
# Dentro:
echo "se perdera" > /fichero.txt
exit
docker rm sin_volumen
docker run -it --name nuevo alpine sh
# Dentro:
ls /fichero.txt # Error: no existe
exitEl fichero no existe en el nuevo contenedor porque no se usó ningún volumen: los datos murieron con el contenedor anterior.
Solución 2
docker volume create mi_volumen
docker volume ls
docker volume inspect mi_volumen # Observa el campo 'Mountpoint'
docker volume rm mi_volumendocker volume inspect revela la ruta real donde Docker almacena los datos del volumen.
Solución 3
docker volume create datos_demo
docker run -d --name db -e POSTGRES_PASSWORD=ejemplo -v datos_demo:/var/lib/postgresql/data postgres:16
docker exec -it db psql -U postgres -c "CREATE DATABASE prueba;"
docker rm -f db
docker run -d --name db -e POSTGRES_PASSWORD=ejemplo -v datos_demo:/var/lib/postgresql/data postgres:16
docker exec -it db psql -U postgres -c "\l" # 'prueba' sigue apareciendoAunque el contenedor se eliminó y se recreó, la base de datos prueba persiste porque los datos viven en el volumen datos_demo.
Conclusión
En esta lección introductoria hemos entendido por qué los contenedores pierden sus datos al eliminarse (su naturaleza efímera) y cómo solucionarlo con volúmenes. Hemos comparado los volúmenes con los bind mounts, aprendido los comandos básicos para gestionarlos (create, ls, inspect, rm), visto cómo montarlos con -v y comprobado con un ejemplo real que los datos de una base de datos sobreviven a la recreación del contenedor. Con esto cierras el Módulo 3 dominando los fundamentos de los contenedores. Más adelante, en el Módulo 5, profundizaremos en los storage drivers, las copias de seguridad y otras opciones avanzadas.
En el siguiente módulo, Módulo 4: Docker Compose, empezando por la lección Introducción a Docker Compose, aprenderás a definir y gestionar aplicaciones con varios contenedores de forma declarativa, mediante un único fichero, en lugar de lanzar cada contenedor a mano.
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
