SSD Nodes Learn 8GB RAM — 연 $66
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-01

docker compose stop과 down 차이

stop은 컨테이너를 보존하고 down은 컨테이너와 프로젝트 네트워크를 제거합니다. 두 명령 모두 named volume은 삭제하지 않으며, 데이터 삭제에는 --volumes가 필요합니다.

간단한 답변

docker compose stop은 컨테이너를 중지하고 디스크에 그대로 둡니다. docker compose down은 컨테이너를 중지한 다음 컨테이너와 프로젝트를 위해 Compose가 생성한 네트워크를 삭제합니다. 두 명령 모두 named volume에는 영향을 주지 않습니다. -v를 추가해야만 데이터베이스가 삭제됩니다. 예를 들어 docker compose down -v과 같이 실행하면 Compose 파일의 volumes 섹션에 선언된 named volume이 삭제됩니다.

이것이 전체 차이점입니다. 이 가이드의 나머지 부분에서는 Postgres volume이 down 후에도 유지되고 down -v에서 삭제되는 과정을 확인합니다. 또한 --force-recreate이 필요한 두 가지 경우를 설명합니다.

docker compose stop: 컨테이너가 계속 존재하는 경우

stop는 각 컨테이너의 주 프로세스에 SIGTERM을 보내고 기다린 다음, 프로세스가 계속 실행 중이면 SIGKILL을 보냅니다. 기본 대기 시간은 10초이며 -t로 변경할 수 있습니다. 아무것도 삭제되지 않습니다. 컨테이너는 ID, 쓰기 가능 계층, IP 예약, 로그를 그대로 유지합니다.

docker compose stop
docker compose ps -a

docker compose ps만 사용하면 실행 중인 컨테이너만 표시하므로, stop 이후에는 빈 표가 출력되고 컨테이너가 삭제되었다고 생각하기 쉽습니다. ps -a는 중지된 컨테이너도 포함하며, 여기에서 각 서비스 옆에 Exited (0)가 표시됩니다. docker compose start로 컨테이너를 다시 시작하면 정확히 동일한 컨테이너를 재사용합니다.

컨테이너가 여전히 존재하므로 볼륨 외부에 컨테이너 내부에 기록한 내용도 그대로 남아 있습니다. 여기에는 docker compose exec로 직접 설치한 패키지와 컨테이너 내부에서 편집한 구성 파일이 포함됩니다. 디버깅할 때 stop를 사용하는 것이 좋은 실질적인 이유는 동일한 상태로 다시 시작할 수 있기 때문입니다.

docker compose down: 컨테이너와 네트워크가 제거됩니다

down은 컨테이너를 중지한 다음 제거합니다. 이 과정에서 프로젝트를 위해 Compose가 생성한 기본 네트워크도 제거합니다. Docker 문서에서는 up이 생성한 컨테이너, 네트워크, 볼륨 및 이미지를 중지하고 제거하는 명령으로 설명합니다. 그러나 볼륨과 이미지는 -v--rmi을 사용해 요청한 경우에만 제거됩니다.

docker compose down
docker compose ps -a
docker network ls

down 이후 ps -a은 해당 프로젝트에 대해 아무것도 출력하지 않으며 <project>_default 네트워크도 사라집니다. name:를 Compose 파일에서 설정하거나 -p를 전달하지 않으면 프로젝트 이름은 디렉터리 이름에서 가져옵니다. 컨테이너의 쓰기 가능 계층에서 변경한 내용은 이제 복구할 수 없습니다. 따라서 down은 컨테이너를 삭제하고 볼륨에 저장한 데이터는 유지하는 명령으로 취급해야 합니다.

잘못된 디렉터리에서 실행하면 no configuration file provided: not found이 표시됩니다. Compose는 사용자가 어떤 프로젝트를 지정했는지 알 수 없으므로 명령을 거부합니다. 프로젝트 디렉터리에 있지 않을 때는 docker compose -f /srv/myapp/compose.yaml down을 사용합니다.

docker compose down은 내 volume을 삭제합니까?

아니요. 최상위 volumes 키 아래에 선언된 named volume은 down보다 오래 유지되며, 연결된 container보다도 오래 유지됩니다. 이 명령에 대해 가장 흔히 우려하는 부분이며, Compose v2에서도 답은 동일합니다.

테스트할 수 있는 stack을 설정합니다. 빈 디렉터리 voltestcompose.yaml 파일을 만들고 다음 내용을 입력합니다.

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

volumes:
  pgdata:

stack을 시작하고 나중에 식별할 수 있는 행을 기록합니다.

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

이제 container를 삭제하고 volume을 확인합니다.

docker compose down
docker volume ls

출력에는 여전히 voltest_pgdata이 표시됩니다. container는 삭제되었지만 데이터는 남아 있습니다. stack을 다시 시작하고 행을 읽습니다.

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

survived을(를) 포함하는 행 하나가 출력됩니다. 새 container는 다른 ID를 가진 별도의 container이며, 동일한 volume에 연결됩니다. 전체적인 내용을 확인하려면 Compose 기본 가이드에서 named volume과 bind mount를 비교하고 각 항목이 host에서 실제로 어디에 위치하는지 확인할 수 있습니다.

down -v가 정확히 삭제하는 항목

-v(긴 형식은 --volumes)은 Compose 파일의 volumes 섹션에 선언된 이름 있는 볼륨과 컨테이너에 연결된 익명 볼륨을 삭제합니다. 같은 스택을 대상으로 실행합니다.

docker compose down -v
docker volume ls

voltest_pgdata이 더 이상 목록에 표시되지 않습니다. 스택을 다시 시작하면 Postgres entrypoint가 빈 데이터 디렉터리를 발견하고 새 클러스터를 초기화합니다. 컨테이너 로그에도 이를 명확히 표시합니다.

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

몇 달 동안 실행 중인 스택에서 해당 블록이 표시되면 볼륨이 삭제된 것입니다. marker 테이블이 사라졌으며, 복구할 수 있는 유일한 방법은 백업입니다.

일부 스토리지는 -v으로 삭제되지 않습니다. bind mount는 호스트 경로이므로 Docker는 해당 마운트만 해제하고 파일은 원래 위치에 그대로 둡니다. external: true로 표시된 볼륨은 이 프로젝트 외부의 항목에 속한다고 선언된 것이므로 Compose가 삭제하지 않습니다. down -v을 실행하기 전에 Compose 파일에서 삭제한 이름 있는 볼륨은 더 이상 선언되어 있지 않습니다. 따라서 Compose는 이를 삭제할 수 없으며 docker volume prune 동안 orphan으로 남겨 둡니다.

마지막 경우는 리팩터링 중에 문제를 일으킵니다. 파일에서 서비스와 해당 볼륨을 제거한 뒤 down -v을 실행하면, 파일에 더 이상 해당 볼륨이 언급되지 않으므로 볼륨이 남습니다. 파일을 편집하기 전에 down -v을 실행해야 하며, 편집한 후에 실행해서는 안 됩니다.

실제로 --force-recreate가 필요한 경우

docker compose up -d는 실행할 때마다 모든 것을 다시 빌드하지 않습니다. Compose는 각 서비스의 확인된 구성 해시를 컨테이너의 레이블로 저장합니다. 해시와 이미지 ID가 모두 일치하면 컨테이너를 그대로 두고 Recreated 대신 Container voltest-db-1 Running을 표시합니다. 이는 대부분의 경우 원하는 동작입니다. up -d를 반복해서 안전하게 실행할 수 있기 때문입니다.

이 때문에 일부 수정 사항이 적용되지 않은 것처럼 보이기도 합니다. Compose는 서비스 정의가 참조하는 파일의 내용이 아니라 확인된 서비스 정의를 해시합니다. 컨테이너에 마운트되어 시작 시 한 번 읽히는 구성 파일은 수정해도 마운트 경로가 변경되지 않으므로 컨테이너 재생성을 트리거하지 않습니다. 서비스는 부팅 시 읽은 값으로 계속 실행됩니다.

docker compose up -d --force-recreate

이 명령은 각 컨테이너를 중지하고 제거한 다음 동일한 정의에서 새 컨테이너를 생성합니다. 마운트된 구성 파일을 수정한 후 사용하고, 컨테이너 상태가 원인을 설명할 수 없을 정도로 달라진 경우에도 사용합니다. 볼륨에는 영향을 주지 않으므로 force recreate를 수행해도 데이터베이스는 유지됩니다. 동일한 태그의 최신 이미지를 사용하려면 pull도 함께 실행해야 합니다.

docker compose pull
docker compose up -d

pull는 새 이미지 ID를 가져옵니다. 그러면 up -d은 실행 중인 컨테이너와 이미지 ID가 다르다는 것을 확인하고 자체적으로 컨테이너를 다시 생성합니다. pull 없이 --force-recreate를 추가하면 동일한 이전 이미지에서 새 컨테이너가 생성됩니다. 따라서 "force recreate를 수행했는데도 여전히 이전 버전입니다"라는 불만이 자주 발생합니다.

docker compose restart는 이 작업을 수행하지 않습니다. 기존 컨테이너를 다시 시작할 뿐이며 Compose 파일을 다시 읽지도 않습니다. 따라서 변경된 환경 변수나 포트 매핑은 적용되지 않습니다. 파일을 수정했다면 up -d를 사용합니다.

유지해야 할 개념 모델

컨테이너는 교체할 수 있습니다. 컨테이너는 프로세스와 얇은 쓰기 가능 계층으로 구성되며, Compose는 파일에서 동일한 컨테이너를 약 1초 만에 다시 빌드할 수 있습니다. 볼륨은 교체할 수 없습니다. 저장소의 어떤 파일로도 다시 생성할 수 없는 상태의 유일한 사본을 보관하기 때문입니다.

모든 Compose 명령은 이 구분에 맞게 동작합니다. stopstart은 컨테이너를 유지합니다. downup은 컨테이너를 교체하면서 볼륨은 유지합니다. down -v은 상태를 제거하는 유일한 일반 명령이므로 명시적인 플래그가 필요합니다. 실제 환경에서 이 명령을 입력하기 전에 백업이 있는지 확인하고, 해당 백업을 최소 한 번 복원해 보았는지 확인합니다.

같은 논리는 secret에도 적용됩니다. POSTGRES_PASSWORD을 통해 설정한 password는 데이터베이스가 처음 초기화될 때만 읽습니다. 따라서 환경 파일에서 password를 변경하고 up -d를 실행하면 password authentication failed for user "postgres"이 됩니다. 컨테이너는 새것이지만 볼륨은 이전 것이며, 이전 볼륨에는 여전히 이전 password가 저장되어 있습니다. Compose가 env 파일과 secret을 확인하는 방법에서는 같은 변수가 두 번 설정될 때 어느 계층의 값이 우선하는지 설명합니다.

실패 유형과 표시되는 문자열

no configuration file provided: not foundcompose.yamldocker-compose.yml가 없는 디렉터리에서 Compose가 실행 중임을 의미합니다. 전체 경로와 함께 -f를 전달합니다.

down에서 network voltest_default has active endpoints가 표시되면 이 프로젝트 외부의 컨테이너가 프로젝트 네트워크에 연결되어 있다는 뜻입니다. 일반적으로 docker run --network로 수동 시작한 컨테이너입니다. 해당 컨테이너를 제거한 다음 down을 다시 실행합니다.

서비스 이름을 변경하거나 서비스를 삭제한 후 Found orphan containers ([voltest-old-1]) for this project가 표시됩니다. 이전 컨테이너에 프로젝트 label이 아직 남아 있기 때문입니다. docker compose down --remove-orphans로 해당 컨테이너를 정리할 수 있으며, 정상적으로 실행 중인 stack에서 사용해도 안전합니다.

수동 docker volume rm에서 Error response from daemon: remove voltest_pgdata: volume is in use가 표시되면 중지된 컨테이너를 포함하여 일부 컨테이너가 아직 해당 volume을 참조하고 있다는 뜻입니다. 먼저 docker compose down을 실행한 다음 volume을 제거하거나, down -v을 사용합니다. 더 큰 프로젝트에서는 다중 서비스 Compose stack을 통해 하나의 프로젝트에 얼마나 많은 volume이 누적될 수 있는지 확인할 수 있습니다.

FAQ

docker compose down을 실행하면 데이터베이스가 삭제됩니까?

데이터베이스가 named volume 또는 bind mount에 있으면 삭제되지 않습니다. down는 컨테이너와 프로젝트 네트워크를 제거하지만, volume은 데이터가 그대로 유지된 채 디스크에 남습니다. 다음 docker compose up -d는 같은 volume을 새 컨테이너에 연결하며, 데이터도 그대로 사용할 수 있습니다. named volume을 제거하는 것은 docker compose down -v뿐이며, 그중에서도 Compose 파일의 volumes 섹션에 선언된 volume만 제거합니다.

다시 사용할 컨테이너에서 stop과 down의 차이는 무엇입니까?

stop는 컨테이너를 유지하므로 docker compose start를 실행하면 같은 writable layer를 사용하는 동일한 컨테이너로 돌아갑니다. 컨테이너 내부에서 직접 설치하거나 수정한 내용도 그대로 남습니다. down는 컨테이너를 삭제하므로 다음 up -d는 image에서 새 컨테이너를 만들며, 직접 수정한 내용은 사라집니다. 디버깅하는 동안에는 stop를 사용합니다.

Compose 프로젝트가 만든 항목을 모두 제거하려면 어떻게 합니까?

docker compose down -v --rmi all --remove-orphans는 컨테이너, 프로젝트 네트워크, 파일에 선언된 named volume, 서비스가 사용한 image, 그리고 프로젝트 이름으로 라벨이 지정된 아직 실행 중인 컨테이너를 제거합니다. bind mount 또는 external: true로 표시된 volume에는 영향을 주지 않습니다. 실행하기 전에 docker volume ls로 삭제할 항목을 확인합니다.

마운트한 config 파일을 변경했는데 컨테이너가 변경 사항을 무시하는 이유는 무엇입니까?

Compose는 확인된 service definition의 hash를 비교하여 컨테이너를 다시 만들지 결정합니다. 이 hash에는 마운트된 파일의 내용이 포함되지 않습니다. 경로가 변경되지 않았으므로 Compose는 시작할 때 읽은 값을 사용하여 컨테이너를 계속 실행합니다. docker compose up -d --force-recreate을 실행하면 파일을 다시 읽는 새 컨테이너가 생성됩니다.

POSTGRES_PASSWORD를 새 값으로 변경했는데 적용되지 않는 이유는 무엇입니까?

Postgres image는 빈 data directory를 초기화할 때만 POSTGRES_PASSWORD을 읽습니다. volume에 이미 초기화된 cluster가 있으므로 이 변수는 무시되고 기존 비밀번호가 계속 적용됩니다. password authentication failed for user "postgres"가 표시됩니다. 실행 중인 데이터베이스 내부에서 ALTER USER으로 비밀번호를 변경하거나, 데이터를 삭제하고 docker compose down -v로 처음부터 다시 시작합니다.