SSD Nodes Learn Hosting plans →
How to do am Matt ConnorBy Matt Connor · Updated 2026-08-07

Docker Compose: stop or down, which one make sense?

stop keeps containers and named volumes, while down removes containers and the project network. Only docker compose down -v deletes named volume data.

Di short answer

docker compose stop go stop the containers and leave dem for disk. docker compose down go stop dem, then delete the containers and the network wey Compose create for the project. Neither command go touch named volume. Your database go only die when you add -v, like for docker compose down -v, wey go remove the named volumes wey dem declare for the volumes section of the Compose file.

Na the whole difference be this one paragraph. The rest of this guide go prove am with one Postgres volume wey you fit watch survive down and disappear under down -v, and e go explain the two cases wey you need --force-recreate.

docker compose stop: containers dey remain

stop dey send SIGTERM go the main process for each container, wait, then send SIGKILL if process still dey alive. Default wait na 10 seconds, and -t dey change am. Nothing dey delete. Container keep its ID, writable layer, IP reservation, and logs.

docker compose stop
docker compose ps -a

docker compose ps by itself dey show only containers wey dey run, so after stop e go print empty table and people go think say containers don disappear. ps -a dey include containers wey don stop, and na there you go see Exited (0) next to each service. Bring dem back with docker compose start; e go reuse the exact same containers.

Because containers still dey exist, anything wey you write inside dem outside a volume still dey there. This include package wey you install by hand with docker compose exec, and config file wey you edit inside the container. Na this be the practical reason to prefer stop while you dey debug: you fit restart into the same state.

docker compose down: container and network go remove

down dey stop the containers first, then e remove dem together with the default network wey Compose create for the project. Docker documentation describe am as stopping containers and removing containers, networks, volumes, and images wey up create. But e only remove volumes and images when you request am with -v and --rmi.

docker compose down
docker compose ps -a
docker network ls

After down, ps -a no dey print anything for the project, and the <project>_default network don disappear. The project name come from the directory name unless you set name: for the Compose file or pass -p. Every change wey you make inside the container writable layer don become impossible to recover, so treat down as command wey throw away the container but preserve the data wey you put for volumes.

If you run am for the wrong directory, you go get no configuration file provided: not found. Compose no know which project you mean, so e refuse to continue. Use docker compose -f /srv/myapp/compose.yaml down when you no dey inside the project folder.

Does docker compose down delete my volumes?

No. Named volume wey you declare under top-level volumes key dey survive down, and e still survive the container wey you attach am to. Na this command dey cause fear pass, but answer no change for Compose v2.

Set up stack wey you fit test. Put this one inside compose.yaml for empty directory wey dem call voltest.

services:
  db:
    image: postgres:16.4
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Start am, then write one row wey you go fit recognise later.

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');"

Now destroy the container and check the volume.

docker compose down
docker volume ls

The output still list voltest_pgdata. The container don comot, but the data no comot. Bring the stack back and read the row.

docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"

You go get one row wey contain survived. The new container na different container with different ID, but e attach to the same volume. If you want understand the bigger picture, the Compose basics guide explain named volumes compared with bind mounts and where each one really dey for the host.

Wetin down -v dey destroy, exactly

-v (long form --volumes) dey remove the named volumes wey Compose file declare for volumes section, plus anonymous volumes wey dey attached to the containers. Run am against the same stack.

docker compose down -v
docker volume ls

voltest_pgdata no dey listed again. Start the stack again, and Postgres entrypoint go find empty data directory, then e go initialise fresh cluster. Container log go talk am plainly.

The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.

If you see that block for stack wey don dey run for months, e mean say dem remove the volume. Your marker table don disappear, and backup na the only way to restore am.

Some storage no dey ever get removed by -v. Bind mount na host path, so Docker only unmount am and your files remain where dem dey. Volume wey get external: true mark mean say e belong to something outside this project, so Compose no go remove am. Named volume wey you delete from Compose file before you run down -v no longer dey declared. Compose no know say e suppose remove am, so e remain behind as orphan for docker volume prune.

That last case dey catch people during refactor. If you remove service and its volume from the file, then run down -v, the volume go survive because the file no longer mention am. Run down -v before you edit the file, no be after.

When you actually need --force-recreate

docker compose up -d no dey rebuild everything every time. Compose dey store hash of each service resolved configuration for the container as label. If the hash match and image ID match, Compose go leave the container as e be, and you go get Container voltest-db-1 Running instead of Recreated. Na the behaviour wey you almost always want, because e make up -d safe to run repeatedly.

Na this one still explain why some edits fit look like say dem do nothing. Compose dey hash the resolved service definition, not the contents of the files wey the definition point to. If you mount config file inside the container and e read am only when startup happen, editing the file no go trigger recreate, because the mount path no change. The service go continue to run with the values wey e read during boot.

docker compose up -d --force-recreate

This one go stop and remove every container, then create new one from the same definition. Use am after you edit mounted config file, and when container don enter state wey you no fit explain. Volumes no go touch, so database go survive force recreate. To use newer image for the same tag, you still need the pull too.

docker compose pull
docker compose up -d

pull go fetch the new image ID, and up -d go then see say the running container get different image ID and recreate am by itself. If you add --force-recreate without pull, you go get new container from the same old image. Na why complaint like "I force recreated and e still be the old version" dey common.

docker compose restart no dey do any of these things. E just restart the existing containers and e no re-read the Compose file at all, so changed environment variable or changed port mapping no go apply. If you edit the file, use up -d.

Di mental model wey you need keep

Containers dey replaceable. Container na process plus small writable layer, and Compose fit build identical one from the file in about one second. Volumes no dey replaceable, because na dem hold the only copy of state wey no file for your repository fit regenerate.

Every Compose verb dey match this separation. stop and start keep the container. down and up replace the container but keep the volume. down -v na the only routine command wey dey remove the state, na why e need explicit flag. Before you type am for anything real, confirm say you get backup wey you don restore at least once.

The same logic apply to secrets. Password wey you set through POSTGRES_PASSWORD na only the first time database initialise am e go read, so if you change am for your environment file and run up -d, e go give you password authentication failed for user "postgres". The container na new one, but the volume na old one, and the old volume still hold the old password. How Compose dey resolve env files and secrets explain which layer go win when you set the same variable twice.

Failure modes and the strings wey you go see

no configuration file provided: not found mean say Compose dey run for directory wey no get compose.yaml and no get docker-compose.yml. Pass -f with the full path.

network voltest_default has active endpoints for down mean say container wey no belong to this project dey attached to the project network. Usually, na container wey person start by hand with docker run --network. Remove that container, then run down again.

Found orphan containers ([voltest-old-1]) for this project dey appear after you rename or delete service. The old container still carry the project label. docker compose down --remove-orphans go clear dem, and e safe to run am for healthy stack.

Error response from daemon: remove voltest_pgdata: volume is in use for manual docker volume rm mean say some container still dey reference the volume, including one wey stop. Run docker compose down first, then remove the volume, or just use down -v. For bigger project, multi service Compose stack show how many volumes one project fit accumulate.

FAQ

Docker compose down dey delete my database?

No, if database dey inside named volume or bind mount. down dey remove containers and project network, but volume remain for disk with all the data intact. The next docker compose up -d go attach new container to the same volume, and the data go still dey there. Na only docker compose down -v dey remove named volumes, and na only volumes wey dem declare for volumes section of Compose file.

Wetin be the difference between stop and down for container wey I wan bring back?

stop dey keep the container, so docker compose start go return you to the same container with the same writable layer. Anything wey you install or edit by hand inside the container go still dey there. down dey delete the container, so the next up -d go build fresh one from the image, and those manual changes go lost. While you dey debug, use stop.

How I fit remove everything wey Compose project create?

docker compose down -v --rmi all --remove-orphans dey remove the containers, project network, named volumes wey dem declare for the file, images wey the services use, and any container wey still get project name label. E no touch bind mounts or volumes wey dem mark external: true. Check wetin you wan lose with docker volume ls before you run am.

Why my container no dey notice the change wey I make to mounted config file?

Compose dey decide whether e go recreate container by comparing hash of the resolved service definition. That hash no include the content of mounted file. The path no change, so Compose leave the container dey run with the values wey e read when e start. Run docker compose up -d --force-recreate to build new container wey go read the file again.

Why my new POSTGRES_PASSWORD no dey work after I change am?

The Postgres image dey read POSTGRES_PASSWORD only when e initialise empty data directory. Your volume already get initialised cluster, so the variable dey ignored and the old password still apply. You go see password authentication failed for user "postgres". Change the password with ALTER USER inside the database wey dey run, or accept say you go lose the data and start again with docker compose down -v.