SSD Nodes Learn 8GB RAM — $66/yr
How to do am Matt ConnorBy Matt Connor · Updated 2026-08-02

Docker Compose stop vs down: Which one you need?

stop dey keep containers and named volumes; down removes containers and di project network. Only --volumes deletes named volume data, so choose carefully.

Di short answer

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

Na di whole difference be this for one paragraph. Di rest of dis guide go prove am with one Postgres volume wey you fit watch survive down and disappear under down -v. E go also explain di two cases wey you need --force-recreate.

docker compose stop: the containers dey stay

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

docker compose stop
docker compose ps -a

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

Because the 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: containers and networks dey removed

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 go 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 dey come from the directory name unless you set name: inside 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 dey 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 the project wey you mean, so e go refuse. Use docker compose -f /srv/myapp/compose.yaml down when you no dey inside the project folder.

docker compose down dey delete my volumes?

No. A named volume wey you declare under top-level volumes key go still dey after down, and e go still dey after the container wey e attach to don commot. Na this one people dey fear pass about the command, and the answer no dey change for Compose v2.

Set up one stack wey you fit test. Put this inside compose.yaml for one 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 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 dey list voltest_pgdata. The container don comot, but the data still dey. 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 full picture, the Compose basics guide explain named volumes against 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 dem declare for the volumes section of the Compose file, 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 the Postgres entrypoint go find empty data directory, so e go initialise fresh cluster. The container log 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 don 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 unmounts am and your files remain where dem dey. A volume wey dem mark external: true mean say dem declare am as belonging to something outside this project, and Compose no dey remove am. A named volume wey you delete from the Compose file before you run down -v no longer dey declared, so Compose no know say e suppose remove am, and e leave am behind as orphan for docker volume prune.

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

When you really need --force-recreate

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

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

docker compose up -d --force-recreate

This one go stop and remove each 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 change, so database go survive force recreate. To use newer image for the same tag, you still need pull.

docker compose pull
docker compose up -d

pull go fetch the new image ID, then up -d go 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 “I force recreated am and e still be the old version” be common complaint.

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

Mental model wey you need keep

Containers fit replace. Container na process plus one thin writable layer, and Compose fit build another identical one from the file within about one second. Volumes no fit replace, because na dem dey hold the only copy of state wey no file for your repository fit generate again.

Every Compose verb match this split. stop and start keep the container. down and up replace the container but keep the volume. down -v na the only routine command wey removes 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.

This same logic apply to secrets. Password wey you set through POSTGRES_PASSWORD na only the first time database dey initialise e go read am, so if you change am for your environment file and run up -d, e give you password authentication failed for user "postgres". The container na new one and the volume na old one, and the old volume still dey hold the old password. How Compose dey resolve env files and secrets explain which layer go win when dem 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 dey outside this project don attach to the project network. Na usually 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 show 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 gather.

FAQ

Docker compose down dey delete my database?

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

Wetin be the difference between stop and down for container wey I wan use again?

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

How I fit remove everything wey Compose project create?

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

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

Compose dey decide whether to recreate container by comparing hash of the resolved service definition, and the hash no include the contents of mounted file. The path no change, so Compose leave the container running 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 dey work. You go see password authentication failed for user "postgres". Change the password with ALTER USER inside the running database, or accept say the data go loss and start again with docker compose down -v.