Por qué se pierden los datos y cómo evitarlo
El escenario típico
Sección titulada «El escenario típico»docker run -d --name mi-db -e POSTGRES_PASSWORD=secreto postgres:16# ... trabajas, creas tablas, cargas datos ...docker rm -f mi-dbdocker run -d --name mi-db -e POSTGRES_PASSWORD=secreto postgres:16# la base de datos está vacía otra vezSin un volumen, todo lo que Postgres escribe vive en la capa de escritura del contenedor (ver Arquitectura) — al borrar el contenedor, esa capa desaparece con él. El segundo docker run crea un contenedor nuevo, sin ninguna relación con los datos del anterior, aunque use el mismo nombre e imagen.
La solución: volumen nombrado
Sección titulada «La solución: volumen nombrado»docker run -d --name mi-db \ -e POSTGRES_PASSWORD=secreto \ -v datos-postgres:/var/lib/postgresql/data \ postgres:16Ahora los datos viven en el volumen datos-postgres, que existe independiente del contenedor. Aunque se borre el contenedor con docker rm -f mi-db, el volumen sigue existiendo:
docker rm -f mi-dbdocker run -d --name mi-db \ -e POSTGRES_PASSWORD=secreto \ -v datos-postgres:/var/lib/postgresql/data \ postgres:16# los datos siguen ahí — el nuevo contenedor se monta sobre el mismo volumenLa regla mental
Sección titulada «La regla mental»Contenedor = el proceso, desechable, se recrea en segundosVolumen = los datos, persistente, sobrevive al contenedorUn contenedor de base de datos se puede borrar y recrear libremente (por ejemplo, para actualizar a una versión nueva de la imagen) sin miedo a perder nada, siempre que los datos estén en un volumen. El contenedor en sí no debería tratarse como “donde viven los datos” — es solo el proceso que los sirve.
Cómo saber si un contenedor tiene sus datos en volumen
Sección titulada «Cómo saber si un contenedor tiene sus datos en volumen»docker inspect --format '{{json .Mounts}}' mi-dbSi la lista está vacía, ese contenedor no tiene ningún volumen — cualquier dato ahí es efímero.
Resetear datos a propósito
Sección titulada «Resetear datos a propósito»A veces sí se quiere empezar de cero (por ejemplo, para probar un schema desde cero):
docker rm -f mi-dbdocker volume rm datos-postgresdocker run -d --name mi-db -e POSTGRES_PASSWORD=secreto -v datos-postgres:/var/lib/postgresql/data postgres:16Borrar el volumen explícitamente (docker volume rm) es lo que de verdad resetea los datos — borrar solo el contenedor, no.
Consideraciones
Sección titulada «Consideraciones»- Este es el error de Docker más común al empezar — perder datos “sin querer” casi siempre es este mismo patrón: correr algo sin
-vpensando que persistía solo. - Ver Levantar Postgres con docker run para el comando completo recomendado, con volumen incluido desde el principio.