티스토리 뷰

카테고리 없음

Docker 컨테이너를 다시 만들었을 때 업로드 파일이 사라지는 저장 구조

생각방 2026. 11. 1. 19:08

목차


    게시판을 새 이미지로 배포한 뒤 글 목록은 남아 있는데 첨부파일만 열리지 않는 상황을 가정해 보겠습니다. 데이터베이스에는 파일 경로가 남았지만, 파일 자체는 교체한 컨테이너 안에만 있었을 수 있습니다. 다만 파일이 보이지 않는다는 사실만으로 삭제를 확정해서는 안 됩니다.  파일의 위치를 기존 컨테이너에 있는건 아닌지, 배포는 정상적으로 됐는지 확인해봐야 합니다. 이 글은 Linux 컨테이너와 Docker Engine을 기준으로 실제 업로드 경로와 저장소 연결을 대조하는 순서를 설명합니다.

    파일의 확인 위치 차이

    재시작과 재생성은 파일에 미치는 영향이 다릅니다

    이미지는 실행에 필요한 파일의 바탕이고, 실행 중 생성한 파일은 기본적으로 해당 컨테이너의 쓰기 가능 계층에 저장됩니다. 마운트하지 않은 경로에 업로드했다면 파일의 수명은 그 컨테이너에 묶입니다. Docker 저장소 문서는 컨테이너가 제거되면 이 계층의 데이터가 유지되지 않는다고 설명합니다.

    같은 컨테이너를 중지했다가 시작하거나 재시작하는 것과, 기존 컨테이너를 삭제하고 새로 만드는 것은 다릅니다. 새 컨테이너는 기존 쓰기 계층을 이어받지 않습니다. 이미지 빌드 때 넣은 기본 파일이 보인다고 해서 운영 중 업로드한 파일까지 이미지에 포함됐다는 뜻도 아닙니다.

    근거: Docker Storage — 쓰기 계층과 저장 방식

    핵심 요약: 업로드 파일의 보존 여부는 같은 이미지 사용 여부보다 실제 기록 위치와 컨테이너 제거 여부에 달려 있습니다.
    업로드 경로와 Mounts의 목적지를 먼저 일치

    업로드 경로와 Mounts의 목적지를 먼저 맞춥니다

    가정한 애플리케이션의 업로드 디렉터리가 /app/uploads라면 먼저 설정 파일과 실행 환경에서 이 절대 경로가 맞는지 확인합니다. 상대 경로를 사용했다면 작업 디렉터리에 따라 다른 곳에 기록됐을 수 있습니다. 아래 명령의 web은 예시 컨테이너 이름이며 실제 이름으로 바꿔야 합니다.

    Mounts에서는 Type, Source 또는 Name, Destination, RW를 확인합니다. /app/uploads 또는 이를 포함하는 상위 경로에 마운트가 있는지 대조합니다. 다른 디렉터리에 볼륨이 연결돼 있어도 실제 업로드 경로가 그 밖이면 파일은 쓰기 계층에 남을 수 있습니다.

    docker inspect web --format '{{json .Mounts}}'
    		docker exec web sh -c 'ls -ld /app/uploads; ls -la /app/uploads'
    		docker volume ls
            	

    두 번째 명령은 컨테이너가 실행 중이고 sh와 ls가 있는 이미지에서 사용합니다. 명령이 없는 최소 이미지라면 해당 환경의 진단 방법을 사용해야 합니다. 조회 결과에 파일이 없을 때는 이전 배포의 볼륨 이름과 호스트 경로도 비교합니다. 이름 있는 볼륨이 남아 있어도 새 컨테이너에 다른 볼륨이 연결됐다면 예전 파일은 보이지 않습니다.

    핵심 요약: 애플리케이션의 실제 저장 경로와 마운트의 Destination이 겹치는지 확인한 뒤 저장소의 동일성을 비교합니다.
    파일이 삭제된 경우와 가려진 경우를 구분

    파일이 삭제된 경우와 가려진 경우를 나눕니다

    볼륨은 컨테이너와 별도 수명을 갖는 Docker 관리 저장소이고, 바인드 마운트는 Docker 데몬 호스트의 특정 경로를 연결합니다. 호스트 디렉터리를 직접 관리해야 한다면 바인드 마운트를 검토하고, Docker가 저장 위치를 관리하도록 하려면 이름 있는 볼륨을 검토할 수 있습니다. 어느 쪽이든 애플리케이션이 그 경로에 쓰도록 설정해야 합니다.

    기존 파일이 있는 경로 위에 마운트하면 원래 파일이 가려질 수 있습니다. 이는 삭제와 다른 상태입니다. 운영 컨테이너의 마운트를 바로 바꾸기보다 배포 설정과 이전 저장소를 먼저 확보하고, 분리한 점검 환경에서 확인하는 편이 원인 구분에 도움이 됩니다.

    확인 결과 판단과 다음 확인
    업로드 경로에 마운트가 없음 기존 컨테이너의 쓰기 계층 저장 가능성 확인
    이전과 다른 볼륨 이름 또는 Source 기존 저장소의 존재와 연결 이력 확인
    같은 저장소인데 파일이 보이지 않음 하위 경로·권한·애플리케이션 삭제 기록 확인
    마운트 추가 직후 기본 파일이 안 보임 기존 경로가 가려졌을 가능성 확인

    근거: Docker Bind mounts — 호스트 경로 연결과 경로 가림

    핵심 요약: 파일 미노출은 삭제, 다른 저장소 연결, 경로 가림을 구분해서 판단해야 합니다.

    재배포 전 파일을 옮기고 재생성 후 읽기를 검증합니다

    예를 들어 아래 실행 옵션은 uploads_data라는 이름 있는 볼륨을 /app/uploads에 연결합니다. 실제 실행 명령에 반영할 때는 서비스의 포트·환경변수 등 기존 설정도 함께 유지해야 합니다. 이 옵션을 추가하는 작업만으로 기존 컨테이너의 업로드 파일이 자동 이전되지는 않습니다.

    기존 컨테이너가 남아 있다면 업로드 변경을 멈추거나 일관성을 확보한 뒤 파일을 별도로 보존하고 목적 저장소로 옮깁니다. 파일 수와 표본 파일 내용을 확인하고, 컨테이너의 실행 계정으로 읽고 쓸 수 있는지도 점검합니다. 기존 컨테이너가 이미 삭제됐고 외부 사본이 없다면 새 볼륨 연결만으로 복구되지는 않습니다.

    --mount type=volume,src=uploads_data,dst=/app/uploads

    전환 후에는 테스트 파일을 업로드하고 새 컨테이너로 재생성한 뒤 같은 파일을 다시 내려받아 확인합니다. DB에 남은 경로와 실제 파일이 맞는지도 함께 대조합니다. 볼륨의 수명이 길다는 사실이 백업을 뜻하지는 않으므로, 볼륨 삭제나 호스트 장애에 대비한 별도 사본과 복원 확인이 필요합니다.

    근거: Docker Volumes — 수명과 기존 데이터 마운트

    핵심 요약: 기존 파일 이전, 같은 저장소 재연결, 재생성 후 다운로드 확인까지 해야 전환 결과를 판단할 수 있습니다.

    FAQ

    컨테이너에 나중에 볼륨을 연결하면 기존 파일도 옮겨집니까?

    기존 쓰기 계층의 파일이 자동으로 이전된다고 가정하면 안 됩니다. Docker는 빈 볼륨을 마운트할 때 컨테이너 경로의 기존 내용을 기본적으로 복사하는 동작이 있지만, 새 컨테이너에 없는 과거 업로드까지 되살리지는 않습니다. 기존 파일을 별도로 확보해 이전 여부를 확인해야 합니다.

    볼륨을 사용하면 다른 서버에서도 파일이 바로 보입니까?

    기본 local 볼륨은 해당 Docker 호스트를 기준으로 합니다. 다른 서버로 배포할 때는 데이터 이전이나 공유 저장소 구성을 별도로 마련해야 합니다.

    컨테이너가 정상 실행되는데 업로드만 실패할 수도 있습니까?

    가능합니다. 마운트 경로가 맞아도 읽기 전용 연결이나 파일 소유권·권한 때문에 쓰기가 실패할 수 있으므로, 실제 업로드 결과와 애플리케이션 오류 기록을 함께 확인합니다.

    결론

    재배포 전에는 업로드 절대 경로, 저장소 종류와 이름, 마운트 목적지를 한 줄로 기록해 두는 것이 좋습니다. 파일이 사라져 보이면 이 기록을 이전 배포와 대조하고, 기존 저장소가 남았는지부터 확인합니다. 보존할 데이터는 컨테이너 교체와 분리해 관리하고, 배포 완료 여부는 화면이 뜨는지만이 아니라 기존 첨부파일을 읽을 수 있는지로 판단합니다.

    참고자료