Docker Compose down vs stop: diferencias y volúmenes
Docker Compose stop conserva contenedores y datos; down elimina contenedores y la red. Ninguno borra volúmenes con nombre, salvo down --volumes.
La respuesta breve
docker compose stop detiene los contenedores y los deja en el disco. docker compose down los detiene y después elimina los contenedores y la red que Compose creó para el proyecto. Ninguno de los dos comandos toca un volumen con nombre. La base de datos sólo desaparece cuando añade -v, como en docker compose down -v, que elimina los volúmenes con nombre declarados en la sección volumes del archivo de Compose.
Esa es toda la diferencia en un párrafo. El resto de esta guía lo demuestra con un volumen de Postgres que puede observar cómo sobrevive a un down y desaparece con un down -v, y explica los dos casos en los que necesita --force-recreate.
docker compose stop: los contenedores permanecen
stop envía SIGTERM al proceso principal de cada contenedor, espera y después envía SIGKILL si el proceso sigue activo. La espera predeterminada es de 10 segundos y -t la cambia. No se elimina nada. El contenedor conserva su ID, su capa escribible, su reserva de IP y sus registros.
docker compose stop
docker compose ps -adocker compose ps por sí solo muestra únicamente los contenedores en ejecución. Por eso, después de stop, muestra una tabla vacía y se puede pensar que los contenedores han desaparecido. ps -a también incluye los contenedores detenidos. Ahí verá Exited (0) junto a cada servicio. Vuelva a iniciarlos con docker compose start, que reutiliza exactamente los mismos contenedores.
Como los contenedores siguen existiendo, todo lo que se haya escrito en ellos fuera de un volumen también permanece. Esto incluye un paquete instalado manualmente con docker compose exec y un archivo de configuración editado dentro del contenedor. Esta es la razón práctica para preferir stop durante la depuración: puede reiniciar con el mismo estado.
docker compose down: se eliminan los contenedores y las redes
down detiene los contenedores y después los elimina, junto con la red predeterminada que Compose creó para el proyecto. La documentación de Docker lo describe como una operación que detiene los contenedores y elimina los contenedores, las redes, los volúmenes y las imágenes creados por up, pero los volúmenes y las imágenes sólo se eliminan cuando se solicitan con -v y --rmi.
docker compose down
docker compose ps -a
docker network lsDespués de down, ps -a no muestra nada para el proyecto y la red <project>_default ya no existe. El nombre del proyecto se obtiene del nombre del directorio, salvo que establezca name: en el archivo de Compose o pase -p. Todos los cambios realizados dentro de la capa escribible de un contenedor son irrecuperables, por lo que debe tratar down como un comando que descarta el contenedor y conserva los datos almacenados en volúmenes.
Si lo ejecuta en el directorio incorrecto, obtiene no configuration file provided: not found. Compose no sabe a qué proyecto se refiere y se niega a continuar. Use docker compose -f /srv/myapp/compose.yaml down cuando no esté en la carpeta del proyecto.
¿docker compose down elimina mis volúmenes?
No. Un volumen con nombre declarado bajo la clave de nivel superior `volumes sobrevive a down` y al contenedor al que estaba asociado. Este es el temor más común sobre el comando, y la respuesta se mantiene en Compose v2.
Configure una pila que pueda usar para realizar pruebas. Guarde lo siguiente en `compose.yaml, dentro de un directorio vacío llamado voltest`.
services:
db:
image: postgres:16.4
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Iníciela y escriba una fila que pueda reconocer más adelante.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"Ahora elimine el contenedor y compruebe el volumen.
docker compose down
docker volume lsLa salida todavía muestra `voltest_pgdata`. El contenedor ha desaparecido, pero los datos no. Vuelva a iniciar la pila y lea la fila.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"Obtendrá una fila que contiene `survived`. El contenedor nuevo es distinto y tiene un ID diferente, pero está asociado al mismo volumen. Si necesita una visión más amplia, la guía básica de Compose explica los volúmenes con nombre frente a los montajes bind y dónde se encuentra realmente cada uno en el host.
Qué destruye exactamente down -v
-v (forma larga: --volumes) elimina los volúmenes con nombre declarados en la sección volumes del archivo de Compose, además de los volúmenes anónimos asociados a los contenedores. Ejecútelo sobre la misma pila.
docker compose down -v
docker volume lsvoltest_pgdata ya no aparece en la lista. Vuelva a iniciar la pila. El entrypoint de Postgres encuentra un directorio de datos vacío e inicializa un clúster nuevo. El registro del contenedor lo indica claramente.
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.Si aparece ese bloque en una pila que lleva meses en ejecución, significa que se eliminó el volumen. La tabla marker se ha perdido y la única forma de recuperarla es usar una copia de seguridad.
-v nunca elimina algunos tipos de almacenamiento. Un bind mount es una ruta del host, por lo que Docker sólo lo desmonta y los archivos permanecen en su ubicación. Un volumen marcado como external: true se declara como perteneciente a algo externo a este proyecto, y Compose nunca lo elimina. Un volumen con nombre que haya eliminado del archivo de Compose antes de ejecutar down -v ya no está declarado. Por tanto, Compose no sabe que debe eliminarlo y queda atrás como huérfano para docker volume prune.
Este último caso suele aparecer durante una refactorización. Elimine un servicio y su volumen del archivo, ejecute down -v y el volumen sobrevivirá porque el archivo ya no lo menciona. Ejecute down -v antes de editar el archivo, no después.
Cuándo se necesita realmente --force-recreate
docker compose up -d no reconstruye todo cada vez. Compose almacena como etiqueta en el contenedor un hash de la configuración resuelta de cada servicio. Si el hash coincide y el ID de la imagen coincide, el contenedor se deja sin cambios y se obtiene Container voltest-db-1 Running en lugar de Recreated. Este es el comportamiento que se necesita casi siempre, porque permite ejecutar up -d de forma segura y repetida.
Por eso algunas modificaciones parecen no tener efecto. Compose calcula el hash de la definición resuelta del servicio, no del contenido de los archivos a los que apunta esa definición. Un archivo de configuración montado en el contenedor y leído una sola vez durante el arranque no provoca una recreación al editarlo, porque la ruta de montaje no ha cambiado. El servicio sigue ejecutándose con los valores que leyó durante el arranque.
docker compose up -d --force-recreateEsto detiene y elimina cada contenedor y crea uno nuevo a partir de la misma definición. Úselo después de editar un archivo de configuración montado y cuando un contenedor haya quedado en un estado que no pueda explicar. Los volúmenes no se modifican, por lo que una base de datos sobrevive a una recreación forzada. Para obtener una imagen más reciente con la misma etiqueta también necesita realizar el pull.
docker compose pull
docker compose up -dpull obtiene el nuevo ID de la imagen y up -d detecta entonces que el ID de la imagen es diferente del del contenedor en ejecución, por lo que lo recrea automáticamente. Añadir --force-recreate sin pull le proporciona un contenedor nuevo a partir de la misma imagen antigua. Por eso es tan habitual escuchar «forcé la recreación y sigue siendo la versión antigua».
docker compose restart no hace nada de esto. Reinicia los contenedores existentes y no vuelve a leer el archivo de Compose, por lo que un cambio en una variable de entorno o en una asignación de puertos no se aplicará. Si editó el archivo, use up -d.
El modelo mental que debe conservar
Los contenedores se pueden reemplazar. Un contenedor es un proceso más una capa grabable fina, y Compose puede crear otro idéntico a partir del archivo en aproximadamente un segundo. Los volúmenes no se pueden reemplazar, porque contienen la única copia del estado que ningún archivo del repositorio puede regenerar.
Cada verbo de Compose corresponde a esta separación. stop y start conservan el contenedor. down y up reemplazan el contenedor y conservan el volumen. down -v es el único comando habitual que elimina el estado, por eso necesita una opción explícita. Antes de escribirlo en un sistema real, confirme que tiene una copia de seguridad que ya haya restaurado al menos una vez.
La misma lógica se aplica a los secretos. Una contraseña establecida mediante POSTGRES_PASSWORD sólo se lee la primera vez que se inicializa la base de datos, por lo que cambiarla en el archivo de entorno y ejecutar up -d le proporciona password authentication failed for user "postgres". El contenedor es nuevo y el volumen es antiguo, y el volumen antiguo todavía contiene la contraseña anterior. Cómo resuelve Compose los archivos de entorno y los secretos explica qué capa prevalece cuando la misma variable se establece dos veces.
Modos de fallo y mensajes que verá
no configuration file provided: not found significa que Compose se está ejecutando en un directorio que no contiene compose.yaml ni docker-compose.yml. Pase -f con la ruta completa.
network voltest_default has active endpoints en down significa que un contenedor externo a este proyecto está conectado a la red del proyecto. Normalmente, se inició manualmente con docker run --network. Elimine ese contenedor y vuelva a ejecutar down.
Found orphan containers ([voltest-old-1]) for this project aparece después de cambiar el nombre de un servicio o eliminarlo. El contenedor antiguo todavía conserva la etiqueta del proyecto. docker compose down --remove-orphans elimina esos contenedores. Es seguro ejecutarlo en una pila en buen estado.
Error response from daemon: remove voltest_pgdata: volume is in use en un docker volume rm manual significa que algún contenedor todavía hace referencia al volumen, incluso si está detenido. Ejecute primero docker compose down y después elimine el volumen, o use directamente down -v. En un proyecto más grande, una pila de Compose con varios servicios muestra cuántos volúmenes puede acumular un proyecto.
FAQ
¿docker compose down elimina mi base de datos?
No, si la base de datos se encuentra en un volumen con nombre o en un montaje bind. down elimina los contenedores y la red del proyecto, pero el volumen permanece en el disco con los datos intactos. El siguiente docker compose up -d conecta un contenedor nuevo al mismo volumen y los datos siguen disponibles. Sólo docker compose down -v elimina los volúmenes con nombre, y únicamente los declarados en la sección volumes del archivo Compose.
¿Cuál es la diferencia entre stop y down para un contenedor que quiero volver a usar?
stop conserva el contenedor, por lo que docker compose start devuelve el mismo contenedor con la misma capa escribible. Todo lo que haya instalado o editado manualmente dentro del contenedor permanece. down elimina el contenedor, por lo que el siguiente up -d crea uno nuevo a partir de la imagen y se pierden esos cambios manuales. Mientras depura, use stop.
¿Cómo elimino todo lo que creó un proyecto de Compose?
docker compose down -v --rmi all --remove-orphans elimina los contenedores, la red del proyecto, los volúmenes con nombre declarados en el archivo, las imágenes utilizadas por los servicios y cualquier contenedor que todavía tenga una etiqueta con el nombre del proyecto. No afecta a los montajes bind ni a los volúmenes marcados con external: true. Compruebe qué elementos va a perder con docker volume ls antes de ejecutarlo.
¿Por qué mi contenedor ignora el cambio que hice en un archivo de configuración montado?
Compose decide si debe volver a crear un contenedor comparando un hash de la definición de servicio resuelta, y ese hash no incluye el contenido de un archivo montado. La ruta no cambió, por lo que Compose deja el contenedor en ejecución con los valores que leyó al iniciarse. Ejecute docker compose up -d --force-recreate para crear un contenedor nuevo que vuelva a leer el archivo.
¿Por qué mi nuevo POSTGRES_PASSWORD no funciona después de cambiarlo?
La imagen de Postgres sólo lee POSTGRES_PASSWORD cuando inicializa un directorio de datos vacío. El volumen ya contiene un clúster inicializado, por lo que la variable se ignora y la contraseña anterior sigue siendo válida. Verá password authentication failed for user "postgres". Cambie la contraseña con ALTER USER dentro de la base de datos en ejecución, o acepte perder los datos y empiece de nuevo con docker compose down -v.