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.txt desaparece 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.

docker run -d --name web -v C:\proyectos\web:/usr/share/nginx/html nginx
  • 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 datos_app
  • 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

docker volume ls
  • Muestra todos los volúmenes existentes en tu sistema, con su driver y su nombre.

Inspeccionar un volumen

docker volume inspect datos_app
  • Muestra los detalles del volumen, incluida la ruta real donde Docker guarda los datos (campo Mountpoint).

Eliminar un volumen

docker volume rm datos_app
  • 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.

docker run -d --name api -v datos_app:/app/data node:18-alpine
  • -v datos_app:/app/data: monta el volumen datos_app en la carpeta /app/data dentro del contenedor.
  • La sintaxis es nombre_volumen:ruta_en_el_contenedor.
  • Todo lo que la aplicación escriba en /app/data se 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:16
  • docker 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 psql -U postgres -c "CREATE DATABASE tienda;"
  • docker exec -it basedatos: entramos en el contenedor en ejecución.
  • psql -U postgres -c "CREATE DATABASE tienda;": creamos una base de datos llamada tienda.

Paso 3: eliminar el contenedor

docker rm -f basedatos
  • 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 que tienda sigue 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 es volumen: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 rm elimina 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
exit

El 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_volumen

docker 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 apareciendo

Aunque 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.

© Copyright 2026. Todos los derechos reservados