코딩왕 미룡

[Docker] Bind Mounts(바인드 마운트) 본문

Docker

[Docker] Bind Mounts(바인드 마운트)

허미룡 2023. 6. 6. 19:09

◦ 소스코드에서 뭔가 변경이 있을 때마다 다시 빌드를 하지 않는 한 변경 사항은 실행 중인 컨테이너에 반영되지 않음

 COPY 명령은 도커 이미지가 생성될 때 폴더의 스냅샷만 복사

 해당 폴더의 모든 변경사항은 이미지에 반영되지 않으므로 컨테이너도 변경 X

 변경 사항이 있을 때마다 전체 이미지를 리빌드하는 것은 굉장히 비효율적이고 번거로움

 

볼륨과 차이점

볼륨(volume) : 

  - 도커가 관리하고 임의로 생성하기 때문에 위치를 알 수 없음

  - 엑세스 불가능

바인드 마운트(bind mount) :

  - 호스트 머신 상에 매핑될 컨테이너의 경로를 설정(위치를 알 수 있음)

  - 다수의 컨테이너에서 공유할 수 있음

  - 소스코드 자체를 바인드 마운트에 넣을 수 있음

     컨테이너는 이를 인식하여 소스코드를 스냅샷에서 복사하는 것이 아닌 바인드 마운트에 복사

      → 그 폴더는 호스트의 폴더에 연결된 것

     컨테이너는 항상 최신 코드에 엑세스 가능

     영구적이지만 편집 가능한 데이터에 적합

 

사용법

-v [호스트 프로젝트 폴더 경로]:/[WORKDIR 경로]

 

🟥 주의

- 바인드 마운트 / named 볼륨 은 컨테이너의 생성(docker run) 시에 설정하는 것

- named 볼륨에 저장된 데이터는 컨테이너가 삭제되어도 존재하며 새 컨테이너 생성 시 같은 볼륨에서 데이터를 사용하거나 저장할 수 있음

- 바인드 마운트는 컨테이너가 삭제되면 덮어씌워진 수정 사항들도 함께 사라짐

    → 다시 바인드 마운트하여 컨테이너를 생성 및 실행하거나 이미지를 다시 빌드해야함

 

※ 콜론(:) 앞에 경로가 붙으면 바인드 마운트(Bind Mount)

docker run -v /app/data …

# 경로가 아닌 것이 붙으면 볼륨으로 취급되어 Named Volume

docker run -v name:/app/data …

# 아무것도 쓰지 않으면(콜론까지) Anonymous Volume 

docker run -v /path/to/code:/app/data …

#이 때 실제 호스트의 폴터를 가리키는 절대 경로를 작성(혹은 $(pwd -W))
#Dockerfile에 작성하는 옵션과 의미가 같음
  1. 익명 볼륨(anonymous volume)은 컨테이너 제거 시 자동 제거
  2. 명명된 볼륨(named volume)은 내장 명령으로 제거 가능
  3. 바인드 마운트는 호스트 머신 내부의 로컬 컨텐츠를 모두 제거해야만 데이터를 모두 지울 수 있음(명령으로도 불가능)

❗ (중요)

※ 바인드 마운트의 경로보다 더 하위의 경로의 볼륨이 있다면 그것이 더 우선시 됨

    → 호스트의 로컬 폴더를 컨테이너 내부의 폴더에 바인딩하고 바인드 마운트에서 사용

    → 이미지 빌드 중에 Dockerfile을 통해 생성된 폴더는 덮어씌우지 않고 그대로 사용

 

ex) docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback -v $(pwd -W):/app -v /app/node_modules feedback-node:bind

 

-v $(pwd -W):/app : 호스트의 로컬 폴더를 컨테이너 내부의 app 폴더에 바인딩함

-v /app/node_modules : 이미지 빌드 시에 RUN npm install 명령을 통해 생성된 node_modules라는 폴더는 덮어씌우지 않고 살려둠

 

❗ COPY 명령을 꼭 사용해야 할까? (중요)

docker run 명령은 개발 중에 사용하는 명령이며 이를 통해 코드의 변경 사항을 실행 중인 컨테이너에 즉시 반영할 수 있음

개발을 마친 후에는 실제로 컨테이너를 서버에 넣음

배포된 환경의 컨테이너는 지속적으로 수정되는 코드가 아닌 완성된 코드의 스냅샷을 활용하여 구동시키므로 COPY 명령을 삭제하지 않고 둬야 함