Saltar al contenido
sudoquest@root
Docker

Volúmenes y datos

Que los datos sobrevivan al contenedor: volúmenes con nombre, carpetas del servidor montadas, copias con tar y limpiar lo que sobra.

25 min de lectura

Lo que un contenedor escribe dentro de sí se va con él: al borrarlo (o al crearlo de nuevo con otra versión de la imagen), sus archivos desaparecen. Para los datos que importan, Docker tiene los volúmenes: directorios que viven aparte de los contenedores y que se montan dentro de ellos. Y para trabajar con archivos del propio servidor, se monta una carpeta de la máquina.

Los ejercicios pasan en el servidor de pruebas de la biblioteca municipal: el catálogo, los préstamos y la web, cada uno con sus datos.

Sin volumen, los datos se van

Un contenedor que escribe en /tmp/x lo escribe en su capa: docker rm y adiós. Por eso la regla es sencilla: lo que tenga que sobrevivir al contenedor, en un volumen.

Volúmenes con nombre

tecnico@srv-pruebas:~$ docker volume create catalogo
catalogo
tecnico@srv-pruebas:~$ docker volume ls
DRIVER    VOLUME NAME
local     catalogo

Con -v nombre:/ruta el volumen se monta en esa ruta del contenedor (y si no existe, se crea). Lo que se escribe ahí queda en el volumen, aunque el contenedor sea de usar y tirar (--rm):

tecnico@srv-pruebas:~$ docker run --rm -v catalogo:/datos alpine sh -c 'echo "El Quijote" > /datos/libros.txt'
tecnico@srv-pruebas:~$ docker run --rm -v catalogo:/datos alpine cat /datos/libros.txt
El Quijote

--mount type=volume,src=catalogo,dst=/datos hace lo mismo, con más letras y sin sorpresas: si algo no cuadra, da error en lugar de crear lo que falta.

Ojo con el nombre: si está mal escrito, -v no da error, crea otro volumen (vacío) y monta ese. Y los montajes se deciden al crear el contenedor: para añadirle o cambiarle uno, se borra y se crea otra vez con su -v. Lo que hay en el volumen no se toca: no se va con el contenedor.

Ejercicio

Que no se pierdan

Las fichas de la biblioteca se perdían cada vez que alguien borraba su contenedor. Arranca el contenedor fichas (con alpine:3.20, haciendo sleep 3600) con un volumen llamado fichas montado en /datos, y escribe en él el archivo /datos/libro.txt.

Preparando la máquina…

¿Dónde están los datos?

Un volumen es un directorio de la máquina, dentro de /var/lib/docker (que solo ve root). docker volume inspect lo dice en Mountpoint:

tecnico@srv-pruebas:~$ docker volume inspect catalogo
[
  {
      "CreatedAt": "2026-10-02T19:08:39Z",
      "Driver": "local",
      "Labels": null,
      "Mountpoint": "/var/lib/docker/volumes/catalogo/_data",
      "Name": "catalogo",
      "Options": null,
      "Scope": "local"
  }
]
tecnico@srv-pruebas:~$ sudo ls -l /var/lib/docker/volumes/catalogo/_data
total 4
-rw-r--r-- 1 root root 11 Oct  2 19:08 libros.txt

Ejercicio

¿Dónde están los datos?

Para la copia de seguridad del servidor hace falta saber dónde guarda Docker los datos del volumen catalogo. Averígualo y apunta esa ruta en ~/donde.txt.

Preparando la máquina…

Carpetas de la máquina

Con una ruta (que empiece por / o por ./) en lugar de un nombre, -v monta esa carpeta del servidor. Lo que se cambie en ella se ve dentro al momento, sin reiniciar nada:

tecnico@srv-pruebas:~$ docker run -d --name web -p 8080:80 -v $HOME/web:/usr/share/nginx/html nginx:1.27-alpine
tecnico@srv-pruebas:~$ echo '<h1>Biblioteca municipal</h1>' > web/index.html
tecnico@srv-pruebas:~$ curl -s localhost:8080
<h1>Biblioteca municipal</h1>

Con :ro al final, el contenedor solo puede leerla:

tecnico@srv-pruebas:~$ docker run --rm -v $HOME/web:/w:ro alpine sh -c 'echo x > /w/y'
sh: can't create /w/y: Read-only file system

Ejercicio

Lo de la carpeta, al momento

La web de la biblioteca se edita en /srv/biblioteca/web del servidor. Arranca el contenedor web (con nginx:1.27-alpine) publicando su 80 en el 8080 y con esa carpeta montada donde nginx tiene sus páginas (/usr/share/nginx/html), y pídela desde la máquina.

Preparando la máquina…

Copias y restauraciones

Para copiar un volumen no hace falta tocar /var/lib/docker: un contenedor de usar y tirar monta el volumen y una carpeta de la máquina, y tar hace el resto.

tecnico@srv-pruebas:~$ docker run --rm -v catalogo:/datos -v $HOME:/copia alpine tar czf /copia/catalogo.tar.gz -C /datos .
tecnico@srv-pruebas:~$ tar tzf catalogo.tar.gz
./
./libros.txt
./nuevo.txt

Restaurar es lo mismo al revés, en el volumen que toque:

tecnico@srv-pruebas:~$ docker run --rm -v catalogo-ayer:/datos -v $HOME:/copia alpine tar xzf /copia/catalogo.tar.gz -C /datos

Para un archivo suelto está docker cp, en los dos sentidos:

tecnico@srv-pruebas:~$ docker cp lector:/datos/libros.txt .
Successfully copied 2.05kB to /home/tecnico/.

Ejercicio

La copia de la noche

Los préstamos están en el volumen prestamos. Haz una copia de lo que tiene en /srv/copias/prestamos.tar.gz, con un contenedor de usar y tirar (alpine:3.20 y tar).

Preparando la máquina…

Ejercicio

Volver a la de ayer

La copia de ayer del catálogo está en /srv/copias/catalogo-ayer.tar.gz. Pon lo que tiene en un volumen nuevo llamado catalogo, con un contenedor de usar y tirar.

Preparando la máquina…

Los que sobran

Algunas imágenes (postgres, por ejemplo) piden un volumen para sus datos (VOLUME en su Dockerfile). Si no le das uno, Docker crea uno anónimo, con un nombre de 64 cifras, que se queda ahí cuando borras el contenedor:

tecnico@srv-pruebas:~$ docker volume ls -f dangling=true
DRIVER    VOLUME NAME
local     catalogo-ayer
local     f20ac252ce6245e5ebb9f0a83e97d63639df338e26c7e22ad67030f5856bb47b
local     prestamos

dangling=true son los que no usa ningún contenedor (ni parado). docker volume prune borra los anónimos que sobran; con -a, todos los que no se usan, también los que tienen nombre.

tecnico@srv-pruebas:~$ docker volume prune -f
Deleted Volumes:
f20ac252ce6245e5ebb9f0a83e97d63639df338e26c7e22ad67030f5856bb47b

Total reclaimed space: 23.33MB

Un volumen que usa algún contenedor no se puede borrar (volume is in use): primero el contenedor. Y docker rm -v borra, con el contenedor, sus volúmenes anónimos.

Ejercicio

Los que sobran

Las pruebas de la semana han dejado volúmenes anónimos que ya no usa nadie. Míralos y bórralos, sin tocar los que tienen nombre (fichas y prestamos son de verdad, aunque ahora no los use ningún contenedor).

Preparando la máquina…

Resumen

Orden Para qué
docker volume create nombre un volumen con nombre
docker run -v nombre:/ruta … montarlo (y crearlo si no está)
docker run -v /carpeta:/ruta[:ro] … montar una carpeta de la máquina
docker volume ls [-f dangling=true] los que hay (los que no usa nadie)
docker volume inspect nombre dónde están sus datos (Mountpoint)
docker run --rm -v vol:/datos -v $PWD:/copia alpine tar czf … copiar un volumen
docker cp contenedor:/ruta . sacar (o meter) un archivo
docker volume rm · docker volume prune [-a] borrar