Cuando trabajamos con contenedores, uno de los desafíos más importantes es la persistencia de datos. Los contenedores son entidades autocontenidas que, por diseño, no tienen acceso al sistema operativo ni a la máquina que los ejecuta. Desde su perspectiva, el contenedor es todo lo que existe, como si fuera una máquina real e independiente. Esto significa que cuando un contenedor muere, sus datos mueren con él, a menos que tomemos medidas para evitarlo.
¿Por qué los datos de un contenedor desaparecen al eliminarlo?
Para entender el problema, imaginemos un escenario práctico con MongoDB [1:27]. Al crear un contenedor de Mongo con docker run -d --name db mongo, podemos conectarnos a él, crear una base de datos y guardar registros. Sin embargo, al eliminar ese contenedor con docker rm -f db [3:24], todo lo que almacenamos se pierde por completo.
Esto ocurre porque cada contenedor nuevo parte de cero, desde su imagen base. Al volver a crear un contenedor de Mongo e intentar buscar los datos anteriores, simplemente no existen [4:07]. La base de datos está vacía porque se trata de una instancia completamente nueva.
Este comportamiento es un problema real cuando tenemos aplicaciones que:
- Generan datos que necesitamos conservar.
- Requieren compartir información con otros contenedores.
- Producen logs que queremos analizar después.
- Necesitan persistir información para otros procesos.
¿Qué es un bind mount y cómo funciona?
Docker ofrece una herramienta llamada bind mount para resolver este problema [4:37]. Un bind mount consiste en atar una ruta del sistema de archivos de la máquina anfitriona con una ruta dentro del contenedor. Todo lo que ocurra en esa ruta dentro del contenedor se espeja automáticamente en la máquina y viceversa.
¿Cómo se configura un bind mount paso a paso?
Primero, necesitamos un directorio en nuestra máquina que sirva como punto de montaje. En el ejemplo, se crea una carpeta vacía llamada mongodata [5:01]. Luego, al ejecutar el contenedor, se utiliza la bandera -v seguida de la ruta completa del directorio local, dos puntos, y la ruta dentro del contenedor:
bash
docker run -d --name db -v /ruta/completa/mongodata:/data/db mongo
Lo que está a la izquierda de los dos puntos es la ruta en nuestra máquina. Lo que está a la derecha es la ruta dentro del contenedor [5:42]. En el caso de MongoDB, los datos se almacenan por defecto en /data/db.
¿Cómo se comprueba que los datos persisten?
Una vez montado el directorio y generados datos dentro del contenedor (por ejemplo, insertando un usuario en la base de datos platzi con db.users.insert({nombre: "Guido"})) [6:35], al revisar el directorio mongodata en la máquina anfitriona encontramos un montón de archivos que no escribimos nosotros [7:12]. Estos archivos aparecieron porque el bind mount espejó todo lo que MongoDB generó internamente.
Al eliminar el contenedor y crear uno nuevo montando el mismo directorio, los datos anteriores siguen disponibles [7:50]. La entrada que se insertó en un contenedor diferente ahora aparece en el nuevo, porque los archivos de la base de datos fueron extraídos gracias al bind mount.
¿Cuáles son los riesgos de usar bind mounts?
Aunque los bind mounts son muy prácticos para sacar o meter datos de un contenedor sin complicaciones, tienen un riesgo de seguridad importante [8:45]. Al usarlos, le estamos dando al contenedor acceso irrestricto a una parte del disco de nuestra máquina.
Si montamos un directorio que contiene datos sensibles, personales o de la compañía, el contenedor tendrá acceso completo a esa información. Si estamos usando una imagen de origen dudoso o que no conocemos bien, no sabemos qué podría hacer con esos datos [9:05].
Por esta razón, Docker ofrece otras formas más seguras de manejar datos que complementan los bind mounts:
- Usar directorios vacíos específicamente creados para este fin.
- Conocer bien la imagen que estamos ejecutando antes de montar rutas sensibles.
- Explorar alternativas como volumes gestionados directamente por Docker.
¿Ya has experimentado con bind mounts en tus proyectos? Comparte tu experiencia y las soluciones que has encontrado para manejar datos entre contenedores.