docker-volumenes-persistencia-datos

Volúmenes en Docker

  • 4 min

En Docker, un volumen es un directorio especial que vive fuera del sistema de archivos del contenedor, en una zona segura de tu disco duro gestionada exclusivamente por Docker.

Ya habíamos visto que los contenedores son efímeros. Es decir, si borras el contenedor, pierdes los datos. Pero normalmente, necesitamos guardar datos.

Para solucionar esto, Docker nos ofrece los volúmenes. Puedes pensar en un volumen como si fuera un disco duro externo USB o un Pendrive.

Tú puedes tener un ordenador (contenedor), enchufarle el USB, guardar ahí tus ficheros, y luego tirar el ordenador a la basura. Si coges un ordenador nuevo y le enchufas ese mismo USB, tus ficheros siguen ahí.

¿Qué es un volumen?

Técnicamente, un volumen es una carpeta que Docker crea en tu máquina anfitriona (Host). Normalmente en Linux está en /var/lib/docker/volumes/.

Esta carpeta tiene un ciclo de vida totalmente independiente al de los contenedores.

  • Puedes borrar el contenedor, y el volumen sigue ahí.
  • Puedes conectar el mismo volumen a varios contenedores a la vez (para compartir datos).
  • Docker se encarga de los permisos y la seguridad.

Los volúmenes son la opción recomendada para Bases de Datos o cualquier dato generado por la aplicación (logs, uploads de usuarios) que deba sobrevivir.

Gestión de volúmenes

Antes de usarlos, vamos a ver cómo se crean y administran. Es muy parecido a gestionar redes o imágenes.

docker volume create mis-datos-db

docker volume ls

Verás algo como:

DRIVER    VOLUME NAME
local     mis-datos-db
Copied!

Si quieres saber dónde está físicamente en tu disco (curiosidad geek):

docker volume inspect mis-datos-db

Busca la propiedad "Mountpoint". Ahí están tus archivos reales.

¡Cuidado aquí! Si borras esto, adiós datos para siempre.

docker volume rm mis-datos-db

Conectando un volumen a un contenedor

Ahora ¿Cómo le decimos a nuestro contenedor que use ese “disco USB”? Usamos el flag -v (o —mount, que es más moderno pero más verboso).

La sintaxis es:

-v <NOMBRE_VOLUMEN>:<RUTA_DENTRO_DEL_CONTENEDOR>
Copied!

Ejemplo: Salvando una base de datos MySQL

Vamos a verlo con un ejemplo. Vamos a lanzar un MySQL, guardar datos, destruirlo y regenerarlo.

Lanzar MySQL con volumen

Sabemos (porque lo hemos mirado en Docker Hub) que MySQL guarda sus datos en /var/lib/mysql. Así que mapeamos nuestro volumen ahí.

docker run -d \
  --name base-datos \
  -e MYSQL_ROOT_PASSWORD=secreto \
  -v mis-datos-db:/var/lib/mysql \
  mysql:5.7
Copied!

Crear datos

Entramos y creamos una tabla de prueba. (No te preocupes por el comando SQL, confía en mí).

docker exec -it base-datos mysql -p
# (escribe la password: secreto)
create database prueba;
exit;
Copied!

Destruir el contenedor

Destruimos el contenedor. Su capa de escritura ha desaparecido.

docker rm -f base-datos
Copied!

Recrear contenedor

Lanzamos un contenedor NUEVO. Puede ser incluso una versión más moderna de MySQL, o llamarse diferente. Lo importante es que le conectamos el mismo volumen.

docker run -d \
  --name base-datos-nueva \
  -e MYSQL_ROOT_PASSWORD=secreto \
  -v mis-datos-db:/var/lib/mysql \
  mysql:5.7
Copied!

Verificar

Entramos a mirar si la base de datos “prueba” existe.

docker exec -it base-datos-nueva mysql -p -e "show databases;"
Copied!

¡Ahí estará! prueba. Los datos han sobrevivido a la destrucción del contenedor.

Limpieza de volúmenes prune

Si has estado jugando mucho con Docker, es probable que tengas gigas de volúmenes anónimos huérfanos comiéndose tu disco.

Para limpiar solo los volúmenes que no están siendo usados por ningún contenedor:

docker volume prune
Copied!

Esto borrará cualquier dato que no esté conectado a un contenedor vivo. Asegúrate de que tienes backups antes de ejecutar esto en un servidor de producción.