Saltar al contenido
Curso Docker y Laravel Sail desde cero
05/10 Dockerizar una aplicación PHP a mano Volúmenes y bind mounts en Docker Compose: persistir MySQL y editar el código sin reconstruir
Tu lectura Quedan 10 min
Lección 5 de 10 · Dockerizar una aplicación PHP a mano

Volúmenes y bind mounts en Docker Compose: persistir MySQL y editar el código sin reconstruir

10 min de lectura Docker Engine 29.8

Hola, bienvenido. Un volumen guarda datos fuera del contenedor para que sobrevivan cuando lo borras, y es lo que necesita MySQL para no perder la base de datos. Un bind mount monta una carpeta de tu máquina dentro del contenedor, y es lo que necesitas para ver los cambios del código sin reconstruir la imagen. En Docker Compose, los 2 se declaran en la clave volumes de cada servicio.

Ya tenemos tasks respondiendo con sus 3 tareas, y ahora toca que no se pierdan. En esta lección vamos a comprobar que ahora mismo perdemos los datos de MySQL, a guardarlos en un volumen con nombre, a cargar el esquema de forma automática y a montar el código de tasks para editarlo en caliente, resolviendo de paso un problema de permisos que vas a ver en Linux y en WSL2.

Los datos de MySQL se pierden

Vamos a empezar por el problema. Ahora mismo tenemos 3 tareas en la base de datos:

Terminal
docker compose exec mysql mysql -utasks -psecret tasks -e "SELECT COUNT(*) FROM tasks"
Salida
mysql: [Warning] Using a password on the command line interface can be insecure. +----------+ | COUNT(*) | +----------+ | 3 | +----------+

Bajamos el stack y lo volvemos a levantar, que es algo que vas a hacer cada día:

Terminal
docker compose down
docker compose up -d

Y repetimos la consulta:

Terminal
docker compose exec mysql mysql -utasks -psecret tasks -e "SELECT COUNT(*) FROM tasks"
Salida
mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1146 (42S02) at line 1: Table 'tasks.tasks' doesn't exist

La tabla ha desaparecido. ¿Qué ha pasado? docker compose down borra los contenedores, y como vimos en la lección de comandos básicos, lo que se escribe dentro de un contenedor se va con él. En realidad es un poco más sutil: la imagen de MySQL declara su carpeta de datos, /var/lib/mysql, como volumen. Cuando no le damos uno nuestro, Docker crea un volumen anónimo, con un nombre aleatorio, para cada contenedor nuevo. El del contenedor anterior sigue en tu disco, pero el contenedor nuevo no sabe nada de él y arranca con uno vacío. Puedes verlos con:

Terminal
docker volume ls
Salida
DRIVER VOLUME NAME local 1674fce09154a4eb24a519c701b8b6ea1e503718c1431847992870bf63ecf778 local b8ab3199da2b6623cba3515ae30427fdc30b4093bb0343b3ac9ca7a02c098b65

Cada uno de esos nombres largos es una base de datos de un contenedor de MySQL que ya no existe, y en tu máquina tendrás uno por cada vez que se ha creado el contenedor de MySQL. Ocupan unos 200 MB cada uno, aunque la base de datos esté casi vacía, y en la lección siguiente veremos cómo limpiarlos.

Lo que queda de esta lección
  1. 02Un volumen con nombre para MySQL
  2. 03Volumen con nombre o bind mount
  3. 04El código con un bind mount
Sigue leyendo gratis Este curso es gratuito. Déjanos tu email y te enviamos un enlace para leerlo entero, junto con el resto de cursos gratuitos.

¿Ya lo habías pedido o entras desde otro dispositivo? Escribe el mismo email: recuperas tu acceso y tu avance.