빌드노트
Compose down 후에도 데이터가 남으면 named volume을 확인한다
Compose down 후에도 데이터가 남는 이유를 컨테이너 layer와 named volume의 수명으로 구별한다. 같은 이미지에서 컨테이너 ID·Mounts·두 파일을 비교하고, 원래 데이터를 지우지 않은 채 새 빈 볼륨으로 확인하는 방법을 설명한다.
Docker Compose 서비스를 down으로 내렸다가 up으로 다시 만들었는데 예전 데이터가 그대로 보인다. 이것만으로 이미지가 교체되지 않았다고 판단할 수는 없다. 컨테이너는 새로 만들어졌어도 같은 named volume을 다시 연결했을 수 있다.
컨테이너 안에서 쓴 파일도 저장 위치에 따라 수명이 다르다. 마운트 밖의 writable layer는 해당 컨테이너가 삭제될 때 함께 사라진다. named volume은 컨테이너와 별도로 남는다. Docker의 볼륨 수명 설명 (새 탭에서 열림)과 compose down 문서 (새 탭에서 열림)에 따르면, 기본 down은 서비스 컨테이너와 네트워크를 제거하지만 named volume까지 제거하지는 않는다.
지금 실행 중인 서비스에서 먼저 확인한다
PowerShell 7과 Docker Compose를 사용하는 경우다. 평소 서비스를 실행하는 Compose 프로젝트 폴더에서, 같은 Docker context를 선택한 상태로 다음 명령을 실행한다. app은 자기 서비스명으로 바꾼다. 기동할 때 -f, -p, --env-file을 지정했다면 조회할 때도 같은 값을 사용한다. 이 명령은 컨테이너를 재생성하거나 데이터를 바꾸지 않는다.
$containerIds = @(docker compose ps -q app)
if ($LASTEXITCODE -ne 0 -or $containerIds.Count -ne 1) { throw '실행 중인 대상 컨테이너 하나를 선택하세요.' }
docker container inspect --format 'id={{.Id}} image={{.Image}}' $containerIds[0]
docker container inspect --format '{{json .Mounts}}' $containerIds[0]
compose ps (새 탭에서 열림)의 -q는 컨테이너 ID를 반환한다. 실행 중인 컨테이너가 없거나 복제본이 여러 개면 위 블록은 멈춘다. 조사할 컨테이너 이름이나 ID를 이미 알고 있다면 두 inspect 명령의 $containerIds[0]에 그 값을 직접 넣어도 된다. inspect 자체가 실패했다면 그 출력을 데이터 보존의 근거로 삼지 않는다. container inspect의 format 옵션 (새 탭에서 열림)으로 필요한 필드만 읽는 방식이다.
id는 컨테이너의 식별자이고 image는 그 컨테이너를 만들 때 사용한 이미지의 식별자다. 재생성 전후에 ID가 달라졌는지 비교한다. 컨테이너 이름은 재사용될 수 있다. ID까지 같다면 재생성을 확인한 것이 아니다. 이미지가 실제로 갱신됐는지는 기대한 이미지와 별도로 대조해야 하며, 데이터가 남았다는 사실만으로 판단하지 않는다.
Mounts에서는 데이터 경로를 덮는 항목의 Type, Name, Destination을 함께 본다. 예를 들어 /data/record.txt를 조사할 때 Type이 volume, Destination이 /data라면 그 파일은 연결된 볼륨 쪽에 있다. Name이 실제 Docker 볼륨명이다. 파일 경로뿐 아니라 /data 같은 상위 디렉터리도 확인한다. 마운트가 겹치면 해당 경로에 가장 구체적으로 적용되는 항목을 읽는다.
재생성 뒤 ID는 바뀌었는데 Destination과 Name이 같다면 같은 이름의 볼륨을 연결한 상태다. 볼륨 내용까지 그대로라는 보장은 아니지만, 예전 데이터가 남는 이유를 설명할 수 있다. Type이 bind라면 호스트 경로를 연결한 것이므로 이 글의 named volume 재사용과 구분한다. Name이 달라졌다면 프로젝트명·볼륨명 치환 값·Docker context가 바뀌었는지 확인한다. 같은 이름인데 내용이 달라졌다면 볼륨을 삭제했다가 다시 만든 적이 있는지, 앱이나 다른 컨테이너가 내용을 썼는지도 조사한다.
같은 이미지에서 파일 두 개의 수명이 달랐다
운영 DB가 아닌 합성 텍스트 파일로 따로 비교했다. 고유한 Compose 프로젝트에 컨테이너 하나를 띄우고, /layer.txt에는 layer-first, named volume을 연결한 /data/record.txt에는 volume-first를 썼다. 두 경로 모두 처음에는 파일이 없었다. 기록 직후의 출력은 다음과 같았다.
/layer.txt=layer-first
/data/record.txt=volume-first
같은 프로젝트와 같은 설정으로 down 후 up을 실행했다. 컨테이너 ID는 98b92b92263e에서 58f922a27a8b로 바뀌었다. 여기서는 ID 앞 12자리만 옮겼다. 두 컨테이너의 이미지 ID는 같았고, /data의 마운트 이름도 nv-lab-49db7b72c2044c9ebf23dc07aa3d62af_keep로 같았다. 파일은 이렇게 달라졌다.
/layer.txt=MISSING
/data/record.txt=volume-first
MISSING은 실험에서 파일이 없음을 표시한 문자열이다. 새 컨테이너의 layer에는 예전 파일이 없었지만, 다시 연결한 볼륨에는 내용이 남았다. 이 실험에서는 이미지를 일부러 바꾸지 않았다. 이미지 갱신 성공을 검증한 결과가 아니라, 이미지 변경 없이도 저장 위치만으로 데이터 보존 여부가 달라진다는 관찰이다.
빈 상태와 비교하려면 새 전용 볼륨을 고른다
기존 데이터를 계속 써야 한다면 같은 볼륨 연결을 유지한다. 빈 상태와 비교할 목적이라면 원래 볼륨을 지우는 대신 새 전용 볼륨을 선택할 수 있다. 다음은 이미 별도로 준비한 합성 데이터 전용 Compose 프로젝트에서 볼륨 이름을 바꾸는 설정이다. 실제 서비스나 운영 DB의 저장소를 전환하는 절차는 아니다.
전용 서비스 app이 data:/data를 마운트하고 있다고 하자. 아래는 전체 Compose 파일이 아니라 최상위 볼륨 선언 부분이다. 기존 이미지·서비스 설정은 유지한다.
volumes:
data:
name: ${NV_LAB_VOLUME:?set NV_LAB_VOLUME}
data는 Compose 안의 참조 이름이고 실제 볼륨명은 name에 넣은 값이다. Compose 볼륨 문서 (새 탭에서 열림)에 따르면 기존 볼륨이 있으면 재사용하며, 명시한 name에는 프로젝트명 접두사를 자동으로 붙이지 않는다. 프로젝트명만 바꿔도 늘 새 저장소가 생긴다고 가정하면 안 된다.
같은 PowerShell 창에서 현재 NV_LAB_VOLUME 값과 inspect의 Name이 일치하는지 확인하고 그 이름을 기록한다. 그런 다음 전용 실습 프로젝트에서만 아래 명령을 하나씩 실행한다. 앞 명령이 실패하면 다음으로 진행하지 않는다. 첫 down이 기존 컨테이너를 제거하므로, 이후 바뀐 볼륨 설정으로 새 컨테이너를 만들게 된다.
docker compose down --timeout 2
$env:NV_LAB_VOLUME = 'nv-fresh-' + [guid]::NewGuid().ToString('N')
docker compose up -d --pull never --wait --wait-timeout 20
사용한 이미지는 전용 프로젝트에 이미 준비돼 있어야 한다. --pull never는 이번 비교에서 이미지를 새로 받지 않도록 한 조건이다. 위의 첫 조회 블록을 다시 실행해 새 ID를 구하고 Mounts.Name이 방금 지정한 이름인지 확인한다. 이름이 이전과 같다면 새 저장소 비교가 성립하지 않는다. 치환 입력과 실제 적용한 Compose 설정부터 확인한다.
합성 파일 실험에서는 새 볼륨을 선택했을 때 /layer.txt와 /data/record.txt가 모두 MISSING이었다. 같은 /data 경로에 다른 저장소를 연결한 결과다. 원래 볼륨 이름으로 돌아가 재생성했을 때 /data/record.txt=volume-first가 다시 보이는 것도 확인했다. 새 볼륨 선택은 기존 데이터의 삭제가 아니다. 확인 뒤 실습 프로젝트를 down으로 종료해도 두 전용 볼륨은 남는다. 나중에 정리할 때는 실습에서 기록한 이름과 소유 라벨을 확인한 자원만 대상으로 한다.
데이터 초기화를 위해 기존 서비스에 무심코 down -v를 붙이지 않는다. 공식 문서에서 -v는 Compose에 선언한 named volume과 연결된 anonymous volume을 제거하는 옵션이다. external: true인 볼륨은 Compose가 수명을 관리하지 않으며 down의 제거 대상도 아니다. 이 실험에서는 외부 볼륨을 연결하지 않았다.
새 볼륨이라고 모든 앱이 빈 데이터로 시작하는 것은 아니다. Docker는 빈 볼륨의 마운트 위치에 이미지 파일이 있으면 기본적으로 복사할 수 있고, 앱도 시작하며 초기 데이터를 만들 수 있다. 볼륨 초기 내용에 관한 문서 (새 탭에서 열림)에 나오는 복사 동작과 앱의 초기화는 별도로 확인해야 한다. 이번 이미지에는 /data의 초기 파일도, 시작할 때 데이터를 쓰는 앱도 없었다.
2026년 10월 21일 Windows 11, PowerShell 7.6.6, Docker Desktop 4.92.0의 Linux 엔진 29.8.0, Compose 5.5.1에서 비교했다. 수정한 조회·볼륨 선택 명령도 새 전용 프로젝트에서 실행해 같은 보존 차이를 확인했다. 볼륨 이름 전환 때 이전 볼륨을 그대로 둔다는 Compose 경고가 나왔으며 실제 연결은 inspect로 확인했다. 관찰은 local 드라이버의 합성 파일에 한정된다. DB 초기화·마이그레이션, 백업·복구, 원격 볼륨 드라이버, 새 이미지로의 배포는 검증하지 않았다.