Watch at Ease세상을 읽고, 일상의 답을 찾다.

기술 · 실용 가이드

Docker Compose 고아 컨테이너 경고: 삭제 전 프로젝트 소유권부터 감사하세요

고아 경고는 삭제 허가가 아닙니다. 유효한 Compose 프로젝트와 소유 라벨, 데이터 마운트를 확인하고 서비스 이름 변경, 프로젝트 이름 충돌, 다른 파일 조합, 일회성 실행을 구분한 뒤 가장 좁은 안전 조치를 선택하세요.

정리 전 두 Docker Compose 프로젝트 그룹의 컨테이너 소유권을 확인하는 독창적인 개념 일러스트
독창적인 개념 일러스트: 경고 컨테이너를 유지·격리·삭제하기 전에 실제 Compose 프로젝트와 서비스 소유자를 증명합니다. Watch at Ease

Docker Compose는 컨테이너가 현재 유효한 프로젝트에는 속하지만 이번 명령의 유효 Compose 모델에는 그 서비스가 없을 때 고아 컨테이너라고 부릅니다. 이는 서비스 이름 변경의 정상 결과일 수도 있고, 무관한 구성이 같은 프로젝트 이름을 쓰거나 다른 파일 조합 또는 중지된 일회성 실행이 남은 결과일 수도 있습니다.

따라서 경고는 증거이지 삭제 허가가 아닙니다. 확인할 것은 `--remove-orphans`의 존재만이 아니라 각 컨테이너를 만든 프로젝트와 서비스, 현재 구성의 관리 의도, 보존해야 할 마운트 데이터입니다.

이 가이드는 읽기 전용 점검부터 시작합니다. 전역 prune이나 볼륨 삭제를 첫 조치로 삼지 않고, 소유권을 확인하기 전에는 경고를 숨기지 않습니다.

1. 경고를 보존하고 정리 결정을 멈추세요

경고 전문, 실행 명령, 작업 디렉터리와 모든 `-f`, `--project-directory`, `-p`, `--project-name` 인수를 저장합니다. 소유권이 불명확한 동안 `docker container prune`, `docker compose down -v`, `--remove-orphans` 재실행을 하지 않습니다.

`docker compose version`, Docker context, Compose 파일과 `COMPOSE_PROJECT_NAME`, 선택된 `.env`를 기록합니다.

`docker ps -a --no-trunc`로 대상의 전체 ID, 상태, 이름을 남기되 이름보다 라벨과 유효 모델을 증거로 사용합니다.

2. 실제 Compose 프로젝트 이름을 계산하세요

프로젝트 이름 우선순위는 `-p`, `COMPOSE_PROJECT_NAME`, 지정 파일의 마지막 최상위 `name`, 프로젝트 디렉터리 기본 이름, 현재 디렉터리 순서입니다. 기억 속 파일명으로 서로 다른 프로젝트라고 가정하지 않습니다.

같은 파일·profiles·환경·옵션으로 `docker compose config`를 렌더링하고 지원되는 이름 출력 옵션으로 최종 이름과 서비스 목록을 저장합니다.

같은 디렉터리명이나 명시 이름 때문에 충돌했다면 안정적인 서로 다른 프로젝트 이름을 지정하고 유효한 다른 컨테이너는 삭제하지 않습니다.

3. 경고된 컨테이너의 Compose 라벨을 읽으세요

각 정확한 ID에서 `com.docker.compose.project`, `com.docker.compose.service`, `com.docker.compose.project.config_files`, `com.docker.compose.project.working_dir`와 일회성 표시를 `docker inspect` JSON으로 기록합니다. project 라벨이 실제 프로젝트 이름과 다르면 즉시 멈춥니다.

같더라도 서비스가 렌더링 모델에 없다는 사실은 후보임을 뜻할 뿐 삭제 안전성을 증명하지 않습니다.

config file과 working directory 라벨로 파일 이름·순서 변경이나 다른 실행 경로를 추적합니다.

4. 네 가지 원인을 구분하세요

서비스 이름 변경·삭제는 project 라벨은 같고 예전 service가 현재 모델에서 사라진 경우입니다. 버전 관리나 배포 기록으로 의도한 변경인지 확인합니다.

프로젝트 이름 충돌은 project는 같지만 애플리케이션이나 파일 루트가 다른 경우이므로 이름부터 분리합니다. `docker compose run`의 중지된 일회성 컨테이너는 특정 버전에서 누적될 수 있다는 상류 issue가 있지만 모든 경고에 일반화하지 않습니다.

라벨·상태·종료 코드·버전을 확인합니다.

다른 `-f` 조합이나 profile에서 필요한 서비스라면 해당 소유 모델을 기록하고 유지합니다.

5. 마운트와 볼륨을 먼저 감사하세요

각 후보의 bind mount, 이름 있는 볼륨, 익명 볼륨을 `docker inspect`에서 기록하고 서비스 소유자와 백업·복원 기대를 확인합니다. 중지된 컨테이너도 데이터 용도를 알려 주는 유일한 지도일 수 있습니다.

Compose down은 컨테이너·네트워크와 볼륨 제거를 구분합니다. 이름 있는 볼륨은 일회용 계층이 아니며 external volume은 프로젝트 밖에서 관리됩니다.

경고만으로 `-v`를 추가하지 말고, 포트나 작업이 살아 있으면 사용자와 의존성을 먼저 찾습니다.

6. 가장 좁은 조치를 선택하세요

컨테이너가 실제로 오래됐고 현재 프로젝트 소유이며 필요한 작업이 없고 데이터가 보존됐을 때만 같은 파일 조합과 이름의 프로젝트 범위 명령을 사용합니다. `docker compose up --remove-orphans`는 현재 모델에 없는 서비스를 제거하므로 범위를 먼저 증명해야 합니다.

이름 충돌이면 삭제 없이 프로젝트 이름을 바꿉니다. 다른 profile·파일 조합 소유면 유지합니다.

일회성 실행이면 전역 prune 대신 정상 수명 주기와 버전별 수정을 사용합니다. 조치 후 같은 context로 원래 명령을 다시 실행하고 무관한 프로젝트·포트·네트워크·마운트가 변하지 않았는지 확인합니다.

증거 | 가능한 원인 | 가장 작은 안전 조치 project 라벨이 다름 | 소유 불일치 | 중지하고 호출·이름부터 해결 같은 project에서 의도적 개명 후 예전 서비스가 없음 | 확인된 오래된 서비스 | 데이터 보존 후 프로젝트 범위 제거 무관한 파일 루트가 같은 이름 | 프로젝트 이름 충돌 | 고유 이름 지정, 유효 컨테이너 유지 중지된 일회성 컨테이너에 실행 증거가 있음 | 일회성 수명 주기 | 종료 상태·버전 확인 후 그 컨테이너만 처리 다른 지원 파일/profile 조합 소유 | 예상 리소스 | 유지하고 소유 호출 문서화

7. 결과를 검증하고 지원용 장부를 만드세요

모든 경고 컨테이너의 project/service 소유자가 기록되고, 유지 대상은 지원 호출에 속하며, 삭제 대상은 오래됐다고 증명되고, 필요한 마운트가 남고, 원래 명령이 다른 프로젝트를 방해하지 않아야 합격입니다.

지원 요청에는 비밀을 제거한 Compose/Engine 버전, context, 프로젝트 이름, 파일 순서, 컨테이너 ID와 라벨, 상태·종료 코드, 마운트 유형을 넣습니다.

이름 우선순위, 파일 차이, 라벨, 일회성 상태와 정상 수명 주기를 배제한 뒤에만 회귀 가능성을 제기합니다.

자주 묻는 질문

Docker Compose 고아 컨테이너는 무엇인가요? 유효 프로젝트에는 연결돼 있지만 서비스가 현재 모델에 없는 컨테이너입니다. 서비스 삭제, 이름 충돌, 다른 파일/profile 조합, 일회성 실행이 원인일 수 있습니다.

`--remove-orphans`는 항상 안전한가요? 아닙니다. 프로젝트 범위가 정확하고 후보가 오래됐으며 필요한 마운트와 데이터가 보존된 경우에만 안전합니다.

무관한 Compose 파일이 서로의 컨테이너를 보는 이유는? 디렉터리 기본값, 환경 변수, 최상위 name, 명시적 `-p` 때문에 같은 프로젝트 이름으로 해석될 수 있습니다.

`docker container prune`으로 경고를 없애도 되나요? 첫 단계로 사용하지 마세요. 범위가 넓고 소유권을 설명하지 않습니다. 오래됐다고 증명된 컨테이너만 처리하세요.

고아 컨테이너의 이름 있는 볼륨, external volume과 bind mount를 삭제 전에 점검하는 독창적인 개념 일러스트
독창적인 개념 일러스트: 프로젝트 범위의 고아 제거 전에 마운트를 감사하고 데이터를 보존합니다. Watch at Ease