certmundo.
es‑mx

7 min de lectura

¿Cómo usar volúmenes de Docker para guardar datos?

Los volúmenes de Docker son carpetas especiales que guardan datos fuera del contenedor, así esos datos sobreviven aunque el contenedor se detenga o elimine.

El problema que los volúmenes resuelven

Imagina que trabajas en el equipo de tecnología de Liverpool. Tienes un contenedor con una base de datos que registra pedidos en línea. El contenedor funciona bien toda la semana. Llega el viernes y alguien ejecuta docker rm para limpiar el servidor. El lunes por la mañana descubren que todos los pedidos del jueves desaparecieron. Ese es exactamente el problema que los volúmenes resuelven.

Por defecto, los datos que crea un contenedor viven dentro de su capa de escritura. Cuando el contenedor muere, esa capa muere con él. Los volúmenes rompen esa dependencia: guardan los datos en el sistema operativo del servidor, no dentro del contenedor.

El sistema CAJA-ESTANTE

Para entender los volúmenes, usa esta analogía: el contenedor es una caja de cartón y el volumen es un estante fijo en la pared. Puedes tirar la caja y comprar una nueva. El estante sigue ahí con todo lo que pusiste encima.

Este sistema tiene tres piezas:

  1. El volumen — el estante, gestionado por Docker.
  2. El punto de montaje — la ruta dentro del contenedor donde el estante queda visible.
  3. El contenedor — la caja que usa el estante mientras vive.

Cuando montas un volumen en un contenedor, todo lo que ese contenedor escriba en esa ruta se guarda automáticamente en el estante. Si creas un contenedor nuevo y montas el mismo volumen, los datos siguen ahí.

Tres tipos de almacenamiento en Docker

Antes de crear tu primer volumen, conviene conocer las tres opciones que Docker ofrece:

Tipo ¿Quién lo gestiona? Caso de uso típico
Volumen Docker Bases de datos, archivos de app
Bind mount Tú (ruta del host) Desarrollo local, código fuente
tmpfs Memoria RAM Datos temporales sensibles

En esta lección nos enfocamos en volúmenes y bind mounts, que son los que usarás el 95% del tiempo en proyectos reales.

Cómo crear y usar un volumen

Crear un volumen es una sola línea:

docker volume create datos_pedidos

Docker registra ese volumen en su propio directorio interno. Puedes listar todos tus volúmenes así:

docker volume ls

Ahora monta ese volumen cuando inicias un contenedor. Usa la bandera -v seguida del nombre del volumen, dos puntos y la ruta dentro del contenedor:

docker run -d \
  -v datos_pedidos:/app/data \
  --name tienda_liverpool \
  mi_app_tienda:1.0

En este ejemplo, todo lo que la aplicación escriba en /app/data queda guardado en el volumen datos_pedidos. Si eliminas el contenedor tienda_liverpool y creas uno nuevo con el mismo comando, los archivos siguen ahí.

Ejemplo real: base de datos para un sistema de nómina

Supón que desarrollas un sistema de nómina para una empresa con 200 empleados. Usas PostgreSQL como base de datos. Sin volumen, si el contenedor de Postgres se reinicia, pierdes todo el historial de pagos.

Así se lanza PostgreSQL con un volumen:

docker volume create nomina_db

docker run -d \
  --name postgres_nomina \
  -e POSTGRES_PASSWORD=clave_segura \
  -e POSTGRES_DB=nomina \
  -v nomina_db:/var/lib/postgresql/data \
  postgres:15-alpine

La ruta /var/lib/postgresql/data es donde Postgres guarda sus archivos internos. Al montarla en nomina_db, cada registro de empleado, cada cálculo de IMSS y cada comprobante queda persistido en el servidor, no dentro del contenedor.

Si necesitas actualizar Postgres a una versión nueva, simplemente detienes el contenedor viejo, creas uno nuevo con la versión actualizada y montas el mismo volumen. Los datos migran sin problema.

Bind mounts: el volumen del desarrollador

Durante el desarrollo local, necesitas algo diferente: que los cambios en tu código se reflejen en el contenedor sin reconstruir la imagen. Para eso usas un bind mount.

Un bind mount conecta una carpeta de tu computadora directamente con una ruta del contenedor:

docker run -d \
  -v $(pwd)/src:/app/src \
  --name dev_femsa \
  mi_app:dev

Aquí $(pwd)/src es la carpeta src de tu proyecto en tu Mac o Linux. /app/src es donde el contenedor la ve. Cada vez que editas un archivo en src/, el contenedor lo detecta al instante.

Esto es especialmente útil cuando trabajas con herramientas como Nodemon o Flask en modo debug. El servidor se recarga solo al detectar cambios, sin necesidad de hacer docker build cada vez.

Regla importante: usa bind mounts en desarrollo. Usa volúmenes en producción. Los bind mounts dependen de la estructura de carpetas de tu máquina, lo que los hace frágiles en servidores.

Cómo inspeccionar un volumen

Puedes ver los detalles de cualquier volumen con:

docker volume inspect datos_pedidos

Eso te muestra algo así:

[
  {
    "Name": "datos_pedidos",
    "Driver": "local",
    "Mountpoint": "/var/lib/docker/volumes/datos_pedidos/_data",
    "CreatedAt": "2024-03-15T10:30:00Z"
  }
]

El campo Mountpoint te dice exactamente dónde Docker guarda esos datos en tu servidor. En producción, ese directorio debería estar en un disco con respaldos automáticos.

Errores comunes al usar volúmenes

Error 1: Olvidar montar el volumen en el contenedor nuevo

Cuando alguien elimina un contenedor y crea uno nuevo, a veces olvida agregar la bandera -v. El contenedor arranca sin el volumen y la aplicación empieza con datos vacíos. Siempre verifica que el nuevo contenedor tenga el mismo montaje.

Error 2: Confundir volúmenes anónimos con volúmenes nombrados

Si ejecutas docker run -v /app/data mi_imagen sin dar nombre al volumen, Docker crea un volumen anónimo con un ID largo como a3f9c2.... Esos volúmenes son difíciles de rastrear y se acumulan con el tiempo. Siempre dale un nombre descriptivo a tus volúmenes.

Error 3: No limpiar volúmenes huérfanos

Cuando eliminas contenedores, los volúmenes no se eliminan automáticamente. Con el tiempo acumulan gigabytes de datos obsoletos. Limpia volúmenes sin uso con:

docker volume prune

Ese comando elimina solo los volúmenes que no están montados en ningún contenedor activo. Es seguro ejecutarlo para limpiar el servidor.

Error 4: Guardar secretos en volúmenes sin cifrar

Un volumen es una carpeta en disco. Si alguien tiene acceso al servidor, puede leer esos archivos. Nunca guardes contraseñas o tokens de API directamente en un volumen sin cifrado adicional. Para secretos, usa variables de entorno o herramientas como Docker Secrets.

Ejemplo con Docker Compose

En proyectos reales casi siempre usarás Docker Compose para orquestar varios servicios. Aquí un ejemplo para una app de inventario similar a la que podría usar Bimbo en sus plantas:

version: "3.9"

services:
  app:
    image: inventario_bimbo:2.1
    volumes:
      - ./src:/app/src
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: inventario
      POSTGRES_PASSWORD: clave_produccion
    volumes:
      - inventario_db:/var/lib/postgresql/data

volumes:
  inventario_db:

Fíjate en la sección volumes: al final del archivo. Ahí declaras los volúmenes nombrados que usa tu proyecto. Compose los crea automáticamente si no existen. El servicio app usa un bind mount para desarrollo. El servicio db usa un volumen nombrado para persistencia.

Verificar que los datos persisten

Prueba esto en tu máquina para confirmar que los volúmenes funcionan:

# Paso 1: crea un volumen y un contenedor
docker volume create prueba_volumen
docker run -d --name contenedor_a \
  -v prueba_volumen:/datos \
  alpine sh -c "echo 'Hola desde Liverpool' > /datos/archivo.txt && sleep 3600"

# Paso 2: elimina el contenedor
docker rm -f contenedor_a

# Paso 3: crea un contenedor nuevo con el mismo volumen
docker run --rm \
  -v prueba_volumen:/datos \
  alpine cat /datos/archivo.txt

El resultado en pantalla será:

Hola desde Liverpool

El contenedor contenedor_a ya no existe, pero su archivo sigue vivo en el volumen. Eso es exactamente la persistencia que necesitas en producción.

Los volúmenes son el puente entre la naturaleza efímera de los contenedores y la permanencia que exigen los datos reales de negocio.

Puntos clave

  • Un volumen de Docker guarda datos fuera del contenedor. Si el contenedor se elimina, los datos sobreviven en el volumen.
  • Usa volúmenes nombrados en producción (`-v nombre_volumen:/ruta`). Evita los volúmenes anónimos porque son difíciles de rastrear y gestionar.
  • Usa bind mounts en desarrollo local para reflejar cambios de código sin reconstruir la imagen. Nunca los uses en producción porque dependen de la estructura de tu máquina.
  • Declara los volúmenes nombrados en la sección `volumes:` de Docker Compose para que se creen automáticamente al iniciar el proyecto.
  • Ejecuta `docker volume prune` periódicamente para eliminar volúmenes huérfanos y liberar espacio en el servidor.

Comparte esta lección: