Docker에는 -v옵션이 있다. 해당 옵션이 왜 필요한지를 모르겠어서 구글링 해보아도 한국어 설명이 부족한것 같았다. 이에 공식 document를 보고 정리해보고자한다.
도커의 Layer 구조
도커의 컨테이너는 아래와 같은 Layer들로 구성되어있다.
Docker Container는 Image를 기반으로 실행이 된다. 이렇게 실행된 container의 경우 image layer 최상단 층에 container layer를 추가하게 된다. 이때 container layer의 경우 R/W layer이고 나머지 Layer는 Read-Only layer이다. 이는 어찌보면 당연한 구조인데 한개의 docker image로 여러 container를 실행시키고자 한다면 docker image에 해당하는 layer는 수정되면 안 될것이기 때문이다.
따라서 container 내의 파일을 생성, 수정, 삭제 등의 작업을 하게 되면 앞써 말한 container layer에 해당 내용이 반영이 된다.
Docker Container Layer?
그럼 이러한 container를 구동시키면 containery layer의 data들은 host device의 어디에 저장되고 관리될까? 즉, docker container 상에서 생성, 수정, 삭제 되는 정보는 어디에 저장되고 관리될까?
이는 옵션에 따라 달라지게 된다.
1. volume : Volumn은 Docker에 의해서 관리 되는 Host Device file system에 데이터가 저장되는 옵션을 의미한다.
해당 옵션의 경우 파일시스템이 host device와 독립적으로 운영되는 volume이 형성되는 옵션이다.
2. bind mount : Host Device에 임의의 저장소에 저장되는 옵션을 의미한다. 해당 옵션의 경우 다른 프로세스에 의해 해당 파일의 내용이 수정될 수 있는 옵션이다.
3. tmpfs mount : Host Device에 In-Memory에 data들이 저장되는 옵션이다.
여기서 궁금점이 생기게 된다. volume이랑 bind mount가 왜 다르게 다뤄지는것일까? 모두 결국에는 Host Device Storage에 저장되는 건데 말이다.
각각의 역할은 조금 상이하다. 공식 홈페이지에는 좀 더 자세한 설명이 나와있지만 요약을 해보자면
volume | bind mount |
docker의 data를 여러 컨테이너와 공유하거나 다른 호스트(cloud)에서 가져오는 경우. 빠른 I/O가 필요한 경우, CrossPlatform을 예상하고 개발이 진행되는 경우 사용되는 옵션이다. | 개발 환경이 host device와 docker를 오가면서 configuration이나 코드가 공유되는 경우 사용되는 옵션이다. |
공식 문서에서는 bind mount는 필요한 경우에만 사용하고 주로 volume을 통한 개발을 지향하라고 되어있다.
Docker -v vs -mount
Docker에는 default로 파일을 tmpfs로 관리하기 때문에 -v나 -mount 옵션을 통해 mount를 진행해야 된다. 그럼 -v와 -mount는 서로 뭐가 다를까?
-v는 -mount의 여러 옵션들을 한번에 통합하여 설정할 수 있게 해준다.
다음은 터미널에서 각각의 옵션이 어떻게 사용되는지에 대한 예시이다.
1. Volume을 사용해서 data를 mount하는 경우
- volume영역을 생성하는 방법
docker volume create my-vol
- docker 실행시에 mount를 하는 경우
// using -mount option
docker run -d \
--name devtest \
--mount source=myvol2,target=/app \
nginx:latest
// using -v option
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app \
nginx:latest
- docker compose를 사용하여 file을 mount하는 경우
해당 compose에 있는 volume명령어는 myapp이라는 영역이 존재하는 경우 생성하고 이후에는 재사용하게 해준다.
services:
frontend:
image: node:lts
volumes:
- myapp:/home/node/app
volumes:
myapp:
2. Mount를 사용해서 data를 mount 하는 경우
- docker 실행시에 mount를 하는 경우
// -v를 사용하는 경우
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app \
nginx:latest
//-mount를 사용하는 경우
docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
- docker compose를 사용하는 경우
version: "3.9"
services:
frontend:
image: node:lts
volumes:
- type: bind
source: ./static
target: /opt/app/static
volumes:
myapp:
긴 글 읽어주셔서 감사합니다.
틀린 부분이 있으면 댓글을 달아주시면 감사하겠습니다.
📧 : may3210@g.skku.edu
🔗 : https://github.com/RicardoKim
Reference
https://docs.docker.com/storage/storagedriver/
https://docs.docker.com/storage/