Docker 공부 끄적(2)-데이터와 볼륨

JH Bang·2023년 2월 22일
0

개발 지식

목록 보기
7/11

데이터

이미지는 read-only이다.
컨테이너는 read-write 레이어로 이미지 위에 덧씌워지는 개념인데, 이때 컨테이너로부터 생성되는 데이터는 컨테이너가 제거되더라도(중지는 괜찮) 살아있어야 한다. -> 볼륨의 필요성

볼륨

호스트 머신에 있는 디렉터리(폴더)다. 이를 컨테이너에 매핑하여 저장소로 사용하는 것이다.
(매핑된 위치는 도커가 관리한다)

Annonymous volume - 컨테이너가 존재하는 동안만 존재

익명볼륨 사용법은 Dockerfile에 VOLUME 명령어를 추가하면 된다.

FROM node

WORKDIR /app

COPY package.json /app

RUN npm install

COPY . .

EXPOSE 80

VOLUME [ "/app/[저장폴더이름]" ]

CMD ["node", "server.js"]

또는 docker run 시에

-v :/app/[디렉터리]

Named volue - 컨테이너 삭제 후에도 존재

명명 볼륨은 docker run 명령어시 옵션으로

-v [볼륨이름]:[컨테이너 내 저장폴더 경로]

를 붙여준다.

참고로 docker run에 '--rm' 옵션을 주게되면 컨테이너가 중지될 때 삭제되므로 익명 볼륨이 자동으로 제거된다.
하지만 --rm 옵션 없이 컨테이너를 시작하면 컨테이너를 (docker rm 으로) 제거하더라도 익명 볼륨은 제거되지 않으며, 이 상태로 컨테이너를 새로 실행하면 새 익명 볼륨이 생성된다 => 익명 볼륨이 쌓인다.
이는 아래 두 명령어 중 하나로 처리하면 된다.

docker volume rm [볼륨아이디] // docker volume ls로 확인
docker volume prune

Bind mount

그런데 볼륨은 도커에 의해 관리가 되므로 호스트 머신의 어느 경로에 저장돼 있는지 모르게 된다. 따라서 데이터의 영구 저장에는 도움이 있지만, 데이터의 편집은 불가능하다.

따라서 편집이 필요한 경우에는 Bind mount, 즉 유저가 관리하는 경로에 데이터를 저장하여 도커가 해당 데이터를 복사하여 반영하도록 해준다.

이것이 필요한 예로는 html을 편집했을 때 바로 반영시켜야할 필요가 있는 경우다. 그렇지 않으면 도커 이미지를 다시 빌드해야하는 번거로움이 발생한다.

docker run 명령어에 다음 옵션 추가 (-v 옵션은 여러개 추가될 수 있음)

-v [복사될 데이터가 들어있는 폴더의 호스트 머신 상 절대경로]:/app  // /app은 이미지 상 working directory

그 전에 도커가 bind mount에 접근할 수 있는지 확인해야 한다
docker의 preferences -> Resources메뉴의 File sharing
상위폴더가 포함돼 있으면 OK, 그렇지 않으면 추가

그러나 단순히 이렇게 하면 의존성 문제가 발생한다.

왜냐하면

처음에 이미지 빌드 단계 상 Dockerfile에서 COPY . . 으로 모든 폴더가 /app에 복사된다.
그런 다음 모든 dependencies가 설치된다.

그런데 컨테이너 run 단계에서 마운트를 컨테이너에 바인딩하면 /app의 모든 내용을 로컬 폴더에 덮어쓰게 된다. node install은 이미지 상에서 이뤄지므로 로컬에는 없다. 그런 상황에서 로컬 폴더를 /app에 마운트 하기 때문에 의존성 문제가 생기는 것.

따라서 Dockerfile의 VOLUME [ "/app/[저장폴더이름]" ] 부분을 삭제하고
docker run 시 -v 옵션으로 dependency가 저장되는 경로에 대해 익명 볼륨을 추가한다. 익명 볼륨은 외부경로보다 컨테이너 내부에 설정된 경로를 우선하게 되므로 따라서 특정 데이터를 lock하는 데 사용된다.

-v :/app/node_modules
-v [단순 이름]:/app				-> 명명 볼륨
-v :/app						-> 익명 볼륨
-v [호스트 머신 경로]:/app			-> mount binding

노드의 경우 nodemon을 사용하면 서버를 restart할 필요 없이 코드 수정 반영이 가능하다.

bind mount를 하는데 Dockerfile에서 COPY를 하는 이유?
Bind mount는 개발 중에 소스코드 실행을 즉각 확인하기 위한 용도로 배포시에는 사용하지 않게 된다. 따라서 작업 디렉터리의 소스코드를 이미지로 복사해 빌드할 필요가 생기게 된다.

profile
의지와 행동

0개의 댓글