Volúmenes Docker frente a montajes vinculados: Conservar los datos del contenedor de la manera correcta
Elimina un contenedor y sus datos van con él, a menos que los guardes en un lugar más seguro. Conozca la diferencia entre volúmenes, montajes vinculados y tmpfs, cuándo usar cada uno y cómo realizar copias de seguridad de lo que importa.
- La capa grabable de un contenedor se elimina junto con el contenedor, por lo que los datos importantes necesitan un montaje.
- Los volúmenes con nombre son administrados por Docker y son la opción habitual para bases de datos y datos de producción.
- Los montajes enlazados asignan una carpeta de host, lo que los hace ideales para el código en vivo durante el desarrollo.
docker compose down -velimina volúmenes, así que utilícelo con cuidado y mantenga copias de seguridad probadas.
Inicia una base de datos en un contenedor, agrega algunos datos, elimina el contenedor y comienza uno nuevo. Los datos se han ido. Casi todo el mundo aprende esta lección por las malas. Los volúmenes Docker y los montajes de enlace existen para mantener los datos vivos más allá de la vida útil de cualquier contenedor.
Esta guía explica cómo funciona cada uno y cómo elegir. Los comandos y archivos aquí son ejemplos estándar, basados en el comportamiento documentado de Docker, y no los ejecutamos para este artículo, así que pruébelos primero con datos desechables. Los detalles pueden diferir entre las versiones de Docker y en Docker Desktop. Si eres nuevo en el mundo de los contenedores, comienza con nuestro tutorial de Docker para principiantes.
Por qué desaparecen los datos del contenedor
Una imagen de Docker está formada por capas de solo lectura. Cuando se inicia un contenedor, Docker agrega una fina capa grabable en la parte superior y cualquier cambio va allí. Esa capa sobrevive a una parada y reinicio, pero se elimina cuando se elimina el contenedor.
docker run -d --name db -e POSTGRES_PASSWORD=devonly postgres:17
# ... create tables and add data ...
docker rm -f db
docker run -d --name db -e POSTGRES_PASSWORD=devonly postgres:17
# The data you added is not there
Esto es por diseño, ya que le permite reemplazar contenedores libremente. Lo que sí significa es que todo lo que necesites conservar debe vivir fuera del contenedor. Hay tres maneras de hacerlo:
| Tipo | almacenado en | ¿Sobrevive a la retirada del contenedor? |
|---|---|---|
| Volumen nombrado | Un área gestionada por Docker | si |
| Montaje de enlace | Una ruta de host que usted elija | si |
| montaje tmpfs | Memoria del anfitrión | No |
Volúmenes de Docker frente a montajes de enlace uno al lado del otro
| Aspecto | Volumen nombrado | Montaje de enlace |
|---|---|---|
| Gestionado por | acoplador | tu |
| Ubicación | Área de almacenamiento de Docker | Cualquier ruta en el host |
| ¿Depende de las carpetas del host? | No | si |
| Editando desde el anfitrión | Incómodo por diseño | Fácil, los cambios aparecen al instante |
| ¿Objetivo vacío precargado a partir de la imagen? | si | No, la ruta del host lo oculta. |
| Comandos CLI de Docker | Sí, docker volume |
No |
| Controladores para almacenamiento remoto | si | No |
| Lo mejor para | Bases de datos, datos de producción. | Código fuente en desarrollo |
Volúmenes nombrados
Un volumen es un almacenamiento creado y administrado por Docker. Te refieres a él por su nombre y no es necesario que te importe dónde vive físicamente.
docker volume create pgdata
docker run -d --name db \
-e POSTGRES_PASSWORD=devonly \
-v pgdata:/var/lib/postgresql/data \
postgres:17
Ahora los archivos de la base de datos se encuentran en pgdata. Elimine el contenedor y comience uno nuevo con el mismo volumen, y sus datos seguirán ahí. En Linux, los volúmenes normalmente se encuentran en /var/lib/docker/volumes/, pero no debes editar esos archivos directamente. En Docker Desktop, viven dentro de una máquina virtual, no en una carpeta normal.
La ruta dentro del contenedor depende de la imagen, así que consulte la documentación de la imagen. Montar en la ruta incorrecta es un error clásico: todo parece funcionar, pero los datos aún se escriben en la capa contenedora. Las versiones principales más recientes de una imagen también pueden cambiar esta ruta, así que lea las notas de la versión antes de actualizar.
Docker creará un volumen con nombre automáticamente si no existe. Un volumen anónimo, creado sin nombre, también funciona, pero obtiene una identificación aleatoria larga y es fácil perderle la pista. Siempre dé nombres a sus volúmenes.
Enlazar monturas
Un montaje de enlace asigna una ruta de host específica directamente al contenedor. Ambas partes ven los mismos archivos inmediatamente. Esto lo hace perfecto para el desarrollo, ya que las ediciones en su editor surten efecto en el contenedor en ejecución sin una reconstrucción:
docker run -d --name web \
-p 8080:80 \
-v "$(pwd)/site:/usr/share/nginx/html:ro" \
nginx:1.27
Edite un archivo en site/, actualice el navegador y verá el cambio. El :ro hace que el montaje sea de solo lectura dentro del contenedor, lo cual es un buen hábito cuando el contenedor no necesita escribir allí.
Las monturas vinculantes tienen algunas desventajas:
- Te vinculan al host. La ruta debe existir en cada máquina, por lo que las configuraciones son menos portátiles.
- Ocultan el contenido de la imagen. Si montas sobre
/app, todo lo que la imagen tenía allí se vuelve invisible. Un ejemplo común es la desaparición denode_modules. - Exponen el host. Un contenedor con un montaje grabable puede cambiar o eliminar archivos de host reales. Nunca monte rutas sensibles como
/o el socket Docker a menos que comprenda completamente el riesgo. - El rendimiento puede variar. En Docker Desktop para macOS y Windows, el uso compartido de archivos cruza los límites de la virtualización y puede ser más lento que en Linux.
montajes tmpfs
Un montaje tmpfs vive en la memoria del host y nunca se escribe en la capa contenedora. Desaparece cuando el contenedor se detiene, por lo que se adapta a archivos temporales, cachés y datos confidenciales de corta duración:
docker run -d --tmpfs /app/cache:size=64m myapp:1.0
tmpfs está disponible en hosts Linux. También puede acelerar las bases de datos en entornos de prueba desechables, donde no le importa conservar los datos.
-v o –mount?
Ambas banderas funcionan. --mount es más largo, pero más explícito y mucha gente lo prefiere en guiones:
# Short form
docker run -v pgdata:/var/lib/postgresql/data postgres:17
# Explicit form
docker run --mount type=volume,source=pgdata,target=/var/lib/postgresql/data postgres:17
# Bind mount, read-only
docker run --mount type=bind,source="$(pwd)"/site,target=/usr/share/nginx/html,readonly nginx:1.27
Hay una diferencia significativa. Con -v, se crea una ruta de host faltante como una carpeta vacía, lo que puede ocultar un error tipográfico. Con --mount y un tipo de enlace, Docker informa un error. Además, con -v, el lado izquierdo decide el tipo: un nombre significa un volumen y una ruta significa un montaje de enlace. Entonces -v data:/x y -v ./data:/x hacen cosas muy diferentes.
Volúmenes en Docker Compose
La mayoría de los proyectos reales declaran el almacenamiento en un archivo Compose. Éste utiliza ambos tipos, cada uno para su función adecuada:
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- ./src:/app/src # bind mount: live code
depends_on:
- db
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: devonly
volumes:
- pgdata:/var/lib/postgresql/data # named volume: data
volumes:
pgdata:
Los volúmenes nombrados deben declararse en la sección de nivel superior volumes. Compose antepone el nombre real al nombre del proyecto. Consulte nuestro tutorial de Docker Compose para obtener un tutorial completo.
Consejo: docker compose down conserva los volúmenes con nombre, pero docker compose down -v los elimina, junto con sus datos. Tenga especial cuidado con los scripts y el historial de shell que incluyen -v.
Comandos de volumen útiles
| Comando | que hace |
|---|---|
volumen de la ventana acoplable ls |
Listas de volúmenes |
nombre de creación de volumen de Docker |
Crea un volumen |
nombre de la inspección del volumen de la ventana acoplable |
Muestra detalles, incluida su ubicación. |
nombre de rm del volumen de Docker |
Elimina un volumen y sus datos. |
poda de volumen de Docker |
Elimina volúmenes no utilizados |
sistema acoplable df -v |
Muestra el uso del disco, incluidos los volúmenes. |
Verifique qué eliminará prune antes de confirmarlo, ya que esto no se puede deshacer. Es posible que los volúmenes que ningún contenedor utiliza actualmente aún contengan datos importantes.
Realizar una copia de seguridad y restaurar un volumen
Se puede realizar una copia de seguridad de un volumen ejecutando un contenedor de corta duración que monte tanto el volumen como una carpeta host:
# Back up
docker run --rm \
-v pgdata:/data:ro \
-v "$(pwd)":/backup \
alpine tar czf /backup/pgdata.tar.gz -C /data .
# Restore into a new volume
docker volume create pgdata_restored
docker run --rm \
-v pgdata_restored:/data \
-v "$(pwd)":/backup \
alpine tar xzf /backup/pgdata.tar.gz -C /data
Para una base de datos activa, copiar archivos como este puede capturar un estado inconsistente. Primero detenga el contenedor, o mejor, use la herramienta propia de la base de datos, como pg_dump para PostgreSQL. Y una copia de seguridad que nunca has restaurado es en realidad sólo una esperanza, así que prueba la restauración.
Permisos de archivos
“Permiso denegado” es el problema más común con los soportes. Los archivos mantienen sus ID numéricos de usuario y grupo en Linux, por lo que si un contenedor se ejecuta como usuario 1000 y la carpeta host pertenece a otro usuario, las escrituras fallarán. Algunas formas de solucionar este problema:
- Ejecute el contenedor con un usuario coincidente:
docker run --user "$(id -u):$(id -g)" ... - Configure la propiedad correcta de su imagen, como se describe en nuestras mejores prácticas de Dockerfile.
- Prefiera volúmenes con nombre para los datos, ya que un nuevo volumen adquiere la propiedad de la carpeta de la imagen cuando se utiliza por primera vez.
- En sistemas que utilizan SELinux, los montajes vinculados pueden necesitar una etiqueta
:zo:Z.
Evite la tentación de chmod 777, como explica nuestra guía de comandos de Linux.
¿Cuál deberías usar?
| Situación | uso |
|---|---|
| Datos de la base de datos | Volumen nombrado |
| Código fuente de edición en vivo | Montaje de enlace |
| Un archivo de configuración de su repositorio | Montaje de enlace de solo lectura |
| Compartir datos entre contenedores | Volumen nombrado |
| Caché temporal o archivos temporales | tmpfs |
| Base de datos de prueba desechable | tmpfs, o sin montaje |
| Código de aplicación en producción. | Constrúyelo en la imagen. |
Esa última fila importa. En producción, el código pertenece a la imagen, por lo que lo que probaste es lo que ejecutas. En los clústeres, el almacenamiento de datos vuelve a funcionar de manera diferente, a través de volúmenes persistentes, que se tratan en la documentación más amplia de Kubernetes. Nuestra guía Docker vs Kubernetes explica cómo se relacionan ambos.
Errores comunes
- Montaje en la ruta incorrecta. Los datos aún residen en la capa contenedora y desaparecen más adelante.
- Ejecutando
down -vcasualmente. Esto elimina los volúmenes nombrados. - Usando rutas relativas con
-v. Formularios como-v data:/xcrean un volumen en lugar de una asignación de carpetas. - Colocar secretos en soportes de enlace grabables. Móntelos como de solo lectura o utilice una función de secretos.
- Apuntar dos contenedores de bases de datos a un volumen. Esto puede dañar los datos.
- No tener copias de seguridad. Un volumen no es una copia de seguridad. Vive en el mismo disco.
Conclusión
La regla general es breve: volúmenes con nombre para los datos, montajes vinculados para el código que está editando y tmpfs para las cosas que no deberían durar. Pruébelo en una base de datos desechable. Cree un volumen con nombre, agregue una fila, elimine el contenedor, inicie uno nuevo y confirme que su fila sobrevivió. Luego practique una copia de seguridad y una restauración antes de que la necesite.
Preguntas frecuentes
¿Cuál es la diferencia entre un volumen Docker y un montaje vinculado?
Docker gestiona un volumen y lo almacena en su propia área. Un montaje de enlace asigna una ruta de host específica que usted controla, directamente al contenedor.
¿Detener un contenedor elimina sus datos?
No. Los datos en la capa de escritura sobreviven a una parada y reinicio. Se pierde cuando se retira el contenedor, a menos que se almacene en un volumen o montaje de enlace.
¿Los volúmenes de Docker persisten después de la composición de Docker?
Sí, los volúmenes con nombre permanecen después de la composición de la ventana acoplable. Agregar el indicador -v los elimina, junto con cualquier dato que contengan.
¿Dónde se almacenan los volúmenes de Docker?
En Linux, normalmente en /var/lib/docker/volumes. En Docker Desktop, viven dentro de una máquina virtual. Utilice la inspección de volumen de la ventana acoplable para ver la ubicación.
¿Pueden varios contenedores compartir un volumen?
Sí, varios contenedores pueden montar un volumen. La aplicación debe manejar el acceso concurrente de forma segura y, por lo general, las bases de datos no deberían compartir archivos de datos de esta manera.
sigue aprendiendo
¿Necesitas ayuda con pruebas, WordPress o SEO?
Ayudamos a los equipos a enviar mejor software y hacer crecer sus sitios. Cuéntenos en qué está trabajando y le sugeriremos un siguiente paso claro.
Más guías sobre testing, IA y desarrollo moderno
¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.
Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas
Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…
Leer artículo →DevOpsExplicación de las variables de entorno: archivos .env, secretos y configuración bien hechos
Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…
Leer artículo →Desarrollo de softwareExplicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429
La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …
Leer artículo →Automatización de pruebasBurlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan
Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…
Leer artículo →Pruebas de softwareExplicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%
Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…
Leer artículo →Bases de datos y SQLDELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno
DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…
Leer artículo →Bases de datos y SQLVistas SQL explicadas: cree, use y evite los errores, con ejemplos
Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…
Leer artículo →Desarrollo de softwareInterfaz TypeScript versus tipo: diferencias reales, probadas con el compilador
Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…
Leer artículo →Desarrollo de softwarePython *args y **kwargs explicados: funciones flexibles con ejemplos claros
Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…
Leer artículo →Desarrollo de softwareFunciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas
Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…
Leer artículo →Inteligencia artificial¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar
¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…
Leer artículo →DevOpsMonitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos
Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…
Leer artículo →DevOpsDocker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta
Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…
Leer artículo →Automatización de pruebasTDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una
TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …
Leer artículo →Desarrollo de softwareGit merge vs rebase: diferencias, ejemplos y cuándo usar cada uno
Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.
Leer artículo →Desarrollo de softwareList comprehension en Python: sintaxis, ejemplos y cuándo evitarla
List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.
Leer artículo →