The difference between docker compose stop and docker compose down is what survives after the containers halt. stop pauses containers and keeps their filesystem, networks, and volumes, so docker compose start resumes them without recreating anything. down tears the project down: it stops containers and removes the containers and networks that up created. This guide covers what each command removes, the flags that extend down, and when to use each one.
TL;DR:
docker compose stoppauses running containers but keeps everything on disk, sodocker compose startbrings the same containers back fast.docker compose downstops and removes the containers and networks created byup, and with-vit also deletes named volumes. Usestopwhen you plan to resume,downwhen you want the project torn down.
stop vs down: The Core Difference
Both commands stop running containers. The difference is what survives after the stop. stop is a pause: containers keep their filesystem, networks, and volumes, and docker compose start resumes them without recreating anything. down is a teardown: it stops the containers and removes the containers and project networks that up created, so the next docker compose up starts from a clean state.
| What happens | docker compose stop | docker compose down |
|---|---|---|
| Running containers | Stopped, kept on disk | Stopped and removed |
| Project networks | Kept | Removed |
| Volumes | Kept | Kept unless -v |
| Images | Kept | Kept unless --rmi |
| How to bring it back | docker compose start | docker compose up |
Stop a project and verify the containers still exist:
docker compose stop
# or stop a single service
docker compose stop webCode language: Bash (bash)
After stop, docker compose ps -a shows the containers with STATUS exited. They are still there, which is why start works:
docker compose ps -a
# containers still exist, STATUS shows "exited"Code language: Bash (bash)
What docker compose down Removes
Per the official docs, down stops containers and removes containers, networks, volumes, and images created by up. The default scope is narrower than that sentence sounds: by default it removes only the containers for services defined in the Compose file, the networks defined in the networks section, and the default network if one is used.
docker compose downCode language: Bash (bash)
What plain down does NOT remove by default: named volumes, anonymous volumes, images, external networks, and external volumes. Each of those needs a flag.
| Flag | Removes | Example |
|---|---|---|
| (none) | Containers + project networks | docker compose down |
-v, --volumes | Named volumes in the volumes section + anonymous volumes | docker compose down -v |
--remove-orphans | Containers for services not in the Compose file | docker compose down --remove-orphans |
--rmi local | Images without a custom tag | docker compose down --rmi local |
--rmi all | All images used by services | docker compose down --rmi all |
-t, --timeout | No removal; shutdown timeout in seconds | docker compose down -t 30 |
The -v flag is the destructive one. It removes named volumes declared in the volumes section plus anonymous volumes attached to containers, and the data inside them is gone:
docker compose down -vCode language: Bash (bash)
Clean up leftovers and images in one pass:
docker compose down --remove-orphans
docker compose down --rmi allCode language: Bash (bash)
start vs restart vs up
These three commands resume or recreate containers. None of them removes anything.
| Command | What it does | Applies compose.yml changes | Removes anything |
|---|---|---|---|
start | Starts existing stopped containers | No | No |
restart | Stops and starts containers without recreating them | No | No |
up | Creates missing containers, recreates changed ones, starts the project | Yes | No |
docker compose start
docker compose restart
docker compose up -dCode language: Bash (bash)
start only works on containers that already exist, so it pairs with stop. restart does not apply compose.yml changes, which surprises people who edit a file and expect restart to pick it up. up is the command that reconciles the running state with the Compose file.
When to Use stop vs down
| Situation | Command | Why |
|---|---|---|
| Pausing work and resuming later | stop | Same containers, fast resume, state kept |
| Freeing memory without losing state | stop | Keeps containers, volumes, and networks |
| Clean teardown after the task | down | Removes containers and networks |
| Resetting a database to empty | down -v | Deletes the volume so it starts fresh |
| Removing leftover containers | down --remove-orphans | Cleans services no longer in the file |
| Freeing disk used by images | down --rmi | Removes images; next up re-pulls |
The rule of thumb: if you will come back to the same environment, stop. If the environment itself is the thing you are done with, down.
Common Gotchas
These failures show up most often when people switch between the two commands without checking what each one removes.
Orphan containers survive a plain down
down only removes containers for services defined in the current Compose file. Containers created for services that were removed from the file, or created with docker compose run, stay behind. --remove-orphans cleans those.
down -v deletes data permanently
-v removes named volumes and their contents. Docker keeps no trash or recycle bin for volumes. Use -v only when you intend to wipe the data, and keep a backup if anything in those volumes matters.
stop and down wait 10 seconds by default
Compose gives a container 10 seconds (stop_grace_period) to stop after SIGTERM before sending SIGKILL. Services with slow shutdown logic can be killed mid-cleanup. Raise the timeout with -t:
docker compose stop -t 30
docker compose down -t 60Code language: Bash (bash)
restart does not apply compose.yml changes
restart stops and starts the existing containers. Configuration changes in compose.yml are not reflected, per the official docs. After editing the file, run up instead.
Legacy docker-compose vs docker compose
Modern Docker Compose v2 is invoked as docker compose (with a space) and is a CLI plugin. The legacy docker-compose binary is deprecated. This article uses the v2 form; if you see docker-compose in old scripts, the lifecycle subcommands behave the same, but update to v2 syntax when you can. See Docker Command Not Found for the CLI/plugin details.
FAQ
Does docker compose stop delete my containers or data?
No. stop sends a stop signal to running containers and leaves them on disk with their networks and volumes intact. The containers keep their current state, and docker compose start brings them back. Data written to named volumes survives because nothing is removed.
Does docker compose down delete volumes?
Not by default. A plain down removes containers and project networks but leaves named volumes, anonymous volumes, and images in place. Volumes are deleted only when you pass -v or –volumes, which removes named volumes declared in the volumes section plus anonymous volumes attached to containers.
What is the difference between docker compose down and docker compose down -v?
The -v flag extends down to also remove volumes. Plain down stops and removes the containers and networks created by up, while keeping volumes and images. down -v additionally deletes named volumes declared in the volumes section and anonymous volumes attached to containers, so the data inside them is lost.
Why does docker compose down leave some containers running?
down only removes containers for services defined in the current compose file. Containers for services that were removed from the file, or created by docker compose run, are treated as orphans and left alone. Add –remove-orphans to remove containers for services not defined in the compose file.
How do I recover data after docker compose down -v?
You cannot recover it from Docker itself. The -v flag deletes the named volumes and their contents, and Docker keeps no backup or trash for volumes. Restore from a backup taken before the command, or switch to bind mounts so data lives on the host outside the Docker volume lifecycle.






