El Problema: Los Contenedores Son Efímeros

Antes de hablar de los volúmenes, debes entender un concepto fundamental: los contenedores Docker son efímeros. ¿Qué significa esto?

Imagina que tienes un contenedor con una base de datos. Insertas datos, todo funciona perfectamente. Luego paras el contenedor, lo reinicias y… los datos han desaparecido. Puf, volatilizados.

Esto sucede porque cada contenedor tiene su propio sistema de archivos aislado que vive y muere con el contenedor mismo. Es como escribir en la arena: en cuanto llega la ola, todo desaparece.

¿Qué es un Volumen Docker?

Un volumen Docker es un mecanismo para guardar los datos fuera del contenedor, de manera que persistan incluso cuando el contenedor se para, reinicia o elimina.

Piensa en los volúmenes como un disco duro externo que conectas a tu contenedor. Los datos se escriben en este “disco externo” y permanecen seguros independientemente de lo que le pase al contenedor.

¿Por Qué Usar Volúmenes?

  • Persistencia: los datos sobreviven al ciclo de vida del contenedor
  • Compartición: varios contenedores pueden acceder a los mismos datos
  • Backup: es más fácil hacer copias de seguridad de los datos
  • Rendimiento: los volúmenes están optimizados para las operaciones I/O
  • Portabilidad: puedes mover los datos entre diferentes hosts

Las Tres Formas de Gestionar los Datos en Docker

Docker ofrece tres enfoques para la gestión de datos. Veámoslos del más recomendado al menos.

1. Volúmenes (Volumes) - La Elección Recomendada

Los volúmenes son gestionados completamente por Docker y guardados en un directorio especial en el host (/var/lib/docker/volumes/ en Linux).

1
2
3
4
5
# Crear un volumen
docker volume create mi-volumen

# Usar el volumen en un contenedor
docker run -v mi-volumen:/app/data mi-imagen

Ventajas:

  • Gestionados por Docker (fáciles de crear, eliminar, inspeccionar)
  • Funcionan en Linux, Windows y Mac
  • Pueden compartirse entre varios contenedores
  • Soportan drivers para almacenamiento remoto (cloud, NFS, etc.)

2. Bind Mounts - Conexión Directa

Los bind mounts conectan una carpeta específica de tu ordenador directamente al contenedor.

1
2
# Conectar una carpeta local al contenedor
docker run -v /ruta/en/tu/pc:/app/data mi-imagen

Cuándo usarlos:

  • Durante el desarrollo, para ver los cambios en el código en tiempo real
  • Cuando necesitas acceder a archivos específicos del sistema host
  • Para compartir configuraciones entre host y contenedor

Atención: los bind mounts dependen de la estructura del sistema de archivos del host, por lo que son menos portables.

3. tmpfs Mounts - Datos Temporales en Memoria

Los tmpfs mounts guardan los datos en la RAM del host, no en disco.

1
docker run --tmpfs /app/temp mi-imagen

Cuándo usarlos:

  • Para datos sensibles que no deben escribirse en disco
  • Para cachés temporales de alto rendimiento
  • Los datos se pierden cuando el contenedor se para (y eso es exactamente lo que quieres)

Comandos Esenciales para los Volúmenes

Crear un Volumen

1
docker volume create nombre-volumen

Listar los Volúmenes

1
docker volume ls

Inspeccionar un Volumen

1
docker volume inspect nombre-volumen

Este comando muestra dónde está físicamente guardado el volumen y otra información útil.

Eliminar un Volumen

1
2
3
4
5
# Eliminar un volumen específico
docker volume rm nombre-volumen

# Eliminar todos los volúmenes no utilizados
docker volume prune

Atención: eliminar un volumen significa perder todos los datos contenidos. No hay papelera ni recuperación.

Ejemplos Prácticos

Ejemplo 1: Base de Datos MySQL con Datos Persistentes

Sin volumen, cada vez que reinicias el contenedor MySQL pierdes todos los datos. Así es cómo resolverlo:

1
2
3
4
5
6
7
8
9
# Crear un volumen para los datos de MySQL
docker volume create mysql-data

# Iniciar MySQL usando el volumen
docker run -d \
  --name mi-mysql \
  -e MYSQL_ROOT_PASSWORD=password123 \
  -v mysql-data:/var/lib/mysql \
  mysql:8

Ahora puedes parar, reiniciar o incluso eliminar y recrear el contenedor: los datos de la base de datos permanecerán intactos en el volumen mysql-data.

Ejemplo 2: Desarrollo Web con Bind Mount

Durante el desarrollo, quieres que las modificaciones al código sean inmediatamente visibles en el contenedor:

1
2
3
4
5
docker run -d \
  --name mi-sitio \
  -p 8080:80 \
  -v $(pwd)/src:/var/www/html \
  php:apache

Cada modificación a los archivos en la carpeta src estará inmediatamente disponible en el contenedor.

Ejemplo 3: Compartir Datos entre Contenedores

Dos contenedores que deben acceder a los mismos archivos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Crear el volumen compartido
docker volume create datos-compartidos

# Contenedor que escribe
docker run -d --name escritor -v datos-compartidos:/data alpine \
  sh -c "while true; do date >> /data/log.txt; sleep 5; done"

# Contenedor que lee
docker run -it --name lector -v datos-compartidos:/data alpine \
  tail -f /data/log.txt

Volúmenes en Docker Compose

Cuando usas Docker Compose, definir los volúmenes es aún más sencillo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
version: '3.8'

services:
  database:
    image: postgres:15
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

  app:
    image: mi-app
    volumes:
      - ./codigo:/app          # Bind mount para desarrollo
      - logs:/app/logs         # Volumen para los logs

volumes:
  postgres-data:    # Volumen gestionado por Docker
  logs:             # Volumen gestionado por Docker

Con un simple docker-compose up, Docker crea automáticamente los volúmenes necesarios.

Backup y Restauración de Volúmenes

Hacer Backup de un Volumen

1
2
3
4
docker run --rm \
  -v nombre-volumen:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz -C /source .

Este comando:

  1. Monta el volumen en solo lectura (ro)
  2. Crea un archivo comprimido en el directorio actual

Restaurar un Backup

1
2
3
4
docker run --rm \
  -v nombre-volumen:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/backup.tar.gz -C /target

Errores Comunes a Evitar

1. Olvidar Usar Volúmenes para las Bases de Datos

Si usas una base de datos en Docker sin volumen, perderás todos los datos. Siempre.

2. Usar Bind Mounts en Producción

Los bind mounts son geniales para el desarrollo, pero en producción usa volúmenes Docker para mayor portabilidad y seguridad.

3. No Hacer Backup de los Volúmenes

Los volúmenes no se incluyen automáticamente en los backups del sistema. Planifica backups regulares.

4. Acumular Volúmenes Huérfanos

Cuando eliminas contenedores, los volúmenes permanecen. Usa periódicamente:

1
docker volume prune

Para eliminar los volúmenes que ya no están conectados a ningún contenedor.

Cuándo Usar Qué: Resumen

EscenarioSolución
Base de datos en producciónVolumen Docker
Desarrollo localBind mount
Datos sensibles temporalestmpfs
Compartición entre contenedoresVolumen Docker
Archivos de configuraciónBind mount o Volumen
Logs de aplicaciónVolumen Docker

Conclusiones

Los volúmenes Docker resuelven uno de los problemas fundamentales de los contenedores: la persistencia de datos. Sin volúmenes, los contenedores serían útiles solo para aplicaciones stateless.

Recuerda las reglas de oro:

  • Usa siempre volúmenes para las bases de datos
  • Usa bind mounts para el desarrollo local
  • Haz backups regulares de los volúmenes importantes
  • Limpia periódicamente los volúmenes huérfanos

Una vez entendido el concepto, los volúmenes se vuelven tan naturales como guardar un archivo en el disco. Y tus datos estarán finalmente seguros, independientemente de lo que le pase a los contenedores.