Docker + Mongo + Volúmenes

Hasta ahora hemos visto como correr un Mongo en un contenedor Docker y cómo restaurar un backup de una base de datos en el mismo contenedor, esto está genial, pero...¿Qué pasa con los datos si borramos el contenedor? Qué los perdemos. Esto puede ser un dolor en desarrollo, sobre todo si hemos metido ciertos juegos de prueba que no tenemos en ningún sitio.

¿Hay forma de guardar los datos fuera del contenedor de MongoDb? Sí, podemos usar los volúmenes de Mongo y decirle que ciertas carpetas las guarde fuera del contenedor, es decir en el disco duro del host.

Manos a la obra

Si venimos del vídeo anterior, podemos ver que tenemos nuestro contenedor disponible y ejecutándose, tecleando el siguiente comando:

docker ps

Lo primero que vamos a hacer es comprobar que perdemos la base de datos de movies si eliminamos el contenedor, para ello ejecutamos el siguiente comando:

docker rm -f my-mongo-db

Ya está eliminado, lo comprobamos:

docker ps

Podíamos hacer un docker ps -a para ver que no esta ni parado.

Seguimos los pasos del video anterior, volvemos a crear e instanciar el contenedor, y entramos en ese en modo interactivo:

docker run --name my-mongo-db -p 27017:27017 -d mongo:4.4.3
docker exec -it my-mongo-db sh

Nos metemos en mongo:

mongo

Y si listamos las bases de datos que tenemos disponibles:

show dbs

Podemos ver que la de my-movies no esta, ¡ouch!

Tecleamos exit dos veces para salir de mongo y del modo interactivo.

Vamos a borarlo todo y empezamos de nuevo:

docker rm -f my-mongo-db

Ahora cuando creemos el contenedor, vamos añadir una opción más, en la que le vamos a indicar que el directorio que hay en el contenedor con path: /data/db (donde por defecto Mongo guarda los ficheros de bases de datos) lo almacene fuera del mismo, en concreto en una carpeta de nuestro disco duro, para ello vamos a usar los volúmenes de Docker, y vamos a darle como nombre de volumen "misdatosmongo".

docker run --name my-mongo-db -d -v misdatosmongo:/data/db -p 27017:27017 mongo:4.4.3

Aquí con -v le indicamos que monte un volumen en local y que el contenido de la ruta que hay en el contenedor /data/db lo almacene en el volumen "misdatosmongo" (Docker también te da la opción de tu indicar una ruta, y también te permite dejar que él le asigne un nombre anónimo al volumen).

Vamos a restaurar el backup que teníamos de la base de datos de películas (seguimos los mismos pasos que en el video anterior):

Primero copiamos los ficheros de nuestro local al contenedor

docker cp backup my-mongo-db:/opt/app

Entramos en nuestro contenedor en modo interactivo

docker exec -it my-mongo-db sh

Nos vamos a la ruta a la que hemos copiado los ficheros que contienen el backup de la base de datos

cd opt
cd app

Y restauramos el backup

mongorestore --db mymovies .

Ahora nos cargamos el contenedor (sin eliminar el volumen):

docker rm -f my-mongo-db

Vamos a volver a crearlo e instanciarlo, indicándole que queremos que use el volumen misdatosmongo:

docker run --name my-mongo-db -d -v misdatosmongo:/data/db -p 27017:27017 mongo:4.4.3

Y ahora si, nuestra base de datos de películas sigue ahí, vamos a comprobarlo:

Entramos en modo interactivo al contenedor

docker exec -it my-mongo-db sh

Nos metemos en mongo:

mongo

Y si vemos las bases de datos que hay:

show dbs

Veremos que aparece my-movies, y puedo, por ejemplo, sacar las películas que pertenecen a la colección movies.

use my-movies
db.movies.find({})

Ya no tenemos que preocuparnos de que se nos borren los datos cuando vayamos a eliminar un contenedor.

Apéndice Manejando volúmenes

Hasta aquí muy bien, pero si esos volúmenes se me van quedando en el disco duro... puedo llegar a llenarlo de volúmenes zombies que no estén en uso, ¿Hay alguna forma de liberar espacio? Si.

Vamos a eliminar el contenedor que habíamos creado

docker rm -f my-mongo-db

Para ver que volúmenes tengo en uso puedo ejecutar el comando

docker volume ls

Aquí vemos nuestro volumen.

Como el volumen que he creado no es anónimo, lo mejor que podemos hacer es borarrlo explicitamente.

Podemos ver la lista de volúmenes que tenemos en nuestro disco duro ejecutando el siguiente comando:

docker volume ls

Y ejecutamos

docker volume rm misdatosmongo

Si he sido un poco despistado y me he ido dejando volúmenes zombies por aquí y por allá, puedo decirle a Docker que borre los volúmenes que no están en uso, con el siguiente comando:

docker volume prune

¿Te gusta el mundo Devops?

En Lemoncode impartimos un Bootcamp Devops Online, en él encontrarás todos los recursos necesarios: clases de los mejores profesionales del sector, tutorías en cuanto las necesites y ejercicios para desarrollar lo aprendido en los distintos módulos. Si quieres saber más puedes pinchar aquí para más información sobre este Bootcamp Devops.