데이터, 볼륨

김장군·2022년 12월 24일
0

Docker

목록 보기
5/6

Docker에서 쓸 수 있는 데이터에는 여러 가지가 있습니다.

  1. 애플리케이션
    • 소스 코드와 이를 돌리기 위한 여러 엘리먼트들.
    • 이미지 빌드할 때 복제되며, 바꿀 수 없습니다.
    • Read-only 데이터이며, 이미지에 담겨 있습니다.
  2. Temporarily 앱 데이터
    • 애플리케이션이 돌아갈 때 생길 수 있는 데이터들.
    • 예를 들면 유저의 인풋 값.
    • 메모리 또는 임시 파일 등에 담기게 될 것입니다.
    • 컨테이너를 끝낼 때 없어져도 되는 데이터들.
    • 읽고 쓸 수 있는 데이터로, 컨테이너가 가지고 있습니다.
  3. Permanent 앱 데이터
    • 애플리케이션이 돌아갈 때 생길 수 있는 데이터들.
    • 하지만 데이터가 남아 있어야 합니다.
    • 예를 들면 유저 어카운트 데이터.
    • 파일 또는 DB 등에 담기게 될 것입니다.
    • 읽고 쓸 수 있는 데이터로 컨테이너가 가지고 있지만, 볼륨의 도움을 받습니다.

볼륨

볼륨에 대해서 알아봅시다.

볼륨은 호스트 머신의 폴더를 말합니다.

호스트 머신에 있는 어떤 폴더가 컨테이너 안의 어떤 폴더로 매핑되는 것입니다.

매핑되어 있는 두 폴더 가운데 하나가 바뀌면 다른 폴더도 똑같이 바뀝니다.

이를 위해 Dockerfile에 VOLUMN 커맨드를 쓰시면 됩니다.

VOLUMN ["/data"]

위 path는 컨테이너 안의 path입니다.

※ Docker는 컨테이너의 파일 시스템 안에서 파일을 움직일 수 없게 해 두었습니다. 컨테이너의 안, 또는 바깥으로의 디렉션으로만 움직일 수 있게 되어 있습니다. 컨테이너의 파일 시스템 안에서 파일을 움직이게 하고 싶다면, 복사하고 나서 파일을 지우는 것으로 해 주시면 됩니다.

※ 볼륨이 호스트 머신의 어디에 있는지 Docker에서는 여러분이 알기를 바라지 않습니다. 혹시나 안다고 하더라도 그 폴더에 대해 어떤 일을 하지 마세요.


볼륨 타입

볼륨에는 2가지 타입이 있습니다.

Anonymous 볼륨, 그리고 named 볼륨입니다.

Anonymous 볼륨은 그 컨테이너에 붙어 있는 볼륨입니다.

컨테이너를 --rm 옵션으로 시작 또는 돌렸을 때,

컨테이너가 할 일을 마치고 사라지면 anonymous 볼륨 또한 같이 사라집니다.

다만 --rm 옵션이 없었다면 그 컨테이너가 멈추었더라도 링크만 끊어질 뿐 anonymous 볼륨은 살아 있습니다.

이러한 볼륨은 쓸 수가 없으니 docker volumn rm VOL_NAME 또는 docker volumn prune 커맨드로 지워 주세요.

위에서 Dockerfile에 VOLUMN 커맨드를 쓰라고 했는데, 이는 anonymous 볼륨을 만듭니다.

Named 볼륨을 만들고 싶다면 아래와 같이 docker run에 -v 옵션을 넣으세요.

docker run -v name:path

Named 볼륨은 컨테이너와 상관없이 살아 있기 때문에

여러 컨테이너가 쓸 수 있습니다.


바인드 마운트

컨테이너 안에서 소스 코드를 바꾼다고 하더라도 그것에는 어떠한 임팩트도 없죠.

애플리케이션은 이미지에 있으며, 이것은 읽을 수만 있는 것이니까요.

하지만 개발을 하다 보면 소스 코드를 조금씩 바꾸면서 애플리케이션이 뜻대로 잘 돌아가는지 체크하고 싶을 때가 많잖아요?

Docker에 이를 위한 어떤 기능이 있지 않을까요..?

네, 바인드 마운트가 있습니다.

이것은 볼륨과 비슷하지만, 다른 게 하나 있습니다.

우리는 볼륨이 호스트의 어디에 있는지 알지 못하지만 바인드 마운트는 알 수 있습니다.

바인드 마운트를 정할 때 우리는 호스트의 어떤 패스와 매핑을 시킬 것인지 함께 정합니다.

docker run -v ABS_PATH_OF_HOST:PATH

어떠한 패스든지 바인드 마운트를 만들 수 있는 것은 아닙니다.

Docker의 Preferences/Resources/FILE SHARING 메뉴에 listing되어 있는 폴더 패스 안에 있어야 합니다.

그렇지 않다면 FILE SHARING에 새 패스를 넣어 주시고요.


Prioritize

여기서 우리는 컨테이너가 볼륨과 바인드 마운트와 어떻게 커뮤니케이션을 하는지 알아봐야 합니다.

컨테이너의 어떤 패스에 볼륨 또는 바인드 마운트를 이을지 정할 수 있죠?

그러면 컨테이너를 돌리거나 시작시킬 때, 볼륨 또는 바인드 마운트에 있는 폴더 또는 파일들을 컨테이너 패스에 덮어쓰게 됩니다.

또한 Docker는 언제나 컨테이너를 시작하거나 돌릴 때 붙을 모든 볼륨을 체크하는데,

붙일 볼륨이 많아 유저가 잘못해서 패스가 겹치는 등의 크래시가 있다면

패스가 더 긴, 그러니까 더 아래 레벨이랑 매핑될 볼륨만 받아들이게 됩니다.

Anonymous 볼륨을 이럴 때 쓸 수 있습니다.

docker run -v PATH로도 anonymous 볼륨을 만들 수 있는데요.

docker run -v "C:\Users\user\Desktop\Project\PROJECT_NAME:/app" -v /app/node_modules ...

위 코드에서 바인드 마운트랑 anonymous 볼륨의 패스가 겹치는데,

anonymous 볼륨의 패스가 더 깊기 때문에

app의 node_modules 디렉터리에 대해선 anonymous 볼륨이랑 이어지고 나머지 app 디렉터리는 바인드 마운트랑 이어지게 되는 것이죠.

마땅하게도 anonymous 볼륨에는 뭐가 없을 거기 때문에 /app/node_modules에는 이미지에서의 /app/node_modules 폴더 및 파일들이 있을 것입니다.

보통 이런 dependency들은 이미지 레벨에서 깔도록 하니까요.

볼륨 또는 바인드 마운트를 만들 때 패스 크래시로 인해서 이미지에서 빌드한 이 dependency들이 지워지지 않도록 할 수 있는 것입니다.

아 물론 이 케이스는 우리의 로컬 애플리케이션 디렉터리에 dependency들이 없을 때를 얘기하는 거고요.


윈도즈에서 WSL2를 쓰는 케이스라면 꼭 알아 두어야 할 게 있습니다.

소스 코드를 바꿀 때마다 dev 서버가 스스로 다시 시작을 하게 해 두었더라도,

WSL2를 쓰고 있다면 잘 안 될 수 있습니다.

이는 소스 코드 및 프로젝트 파일들을 리눅스에 여러분이 두어야 하기 때문인데요,

2가지 방법이 있겠네요.

첫 번째 방법은 윈도즈 패스를 WSL2에 마운트 하는 것입니다.

이를 위해 링크를 남겨 두겠습니다.

두 번째 방법은 WSL2를 윈도즈의 디폴트 터미널로 쓰는 겁니다.


Read-only 볼륨

볼륨은 디폴트로 읽기, 쓰기를 할 수 있으며

이는 컨테이너가 볼륨에서 데이터를 읽기도 하고, 볼륨에 데이터를 쓰기도 할 수 있음을 뜻합니다.

그런데 읽기만 될 수 있게 정할 수 있습니다.

docker run -v "C:\Users\user\Desktop\Project\PROJECT_NAME:/app:ro"

위 코드와 같이 볼륨 또는 바인드 마운트의 패스 뒤에 :ro를 붙이면 됩니다.

이제 Docker는 이 패스 및 아래 패스들에 대해 쓰기를 할 수 없게 됩니다.

물론 호스트 머신 파일 시스템에는 쓰기를 할 수 있고,

컨테이너와, 컨테이너에서 돌아가는 애플리케이션에만 임팩트가 갑니다.

이와 더불어 위와 같이 app 패스에 대해 read-only 세팅을 했다 하더라도

app/feedback 패스에 대해 볼륨 또는 바인드 마운트가 생긴다면 feedback에 대해서는 읽기, 쓰기를 할 수 있게 되고요.


볼륨은 Docker에서 매니지먼트하지만, 볼륨 안을 들여다보거나 Docker가 볼륨에 뭘했는지 살펴볼 수 있습니다.

docker volume --help

위 커맨드를 돌려 보면 여러 가지 기능들이 있다는 걸 알 수 있을 겁니다.

docker volumn inspect VOLUMN_NAME

위 커맨드로 볼륨의 마운트 포인트도 알 수 있습니다.

하지만 이 마운트 포인트 패스가 호스트 머신 파일 시스템이랑은 좀 달라요.

Docker가 여러분의 호스트 머신 파일 시스템에 작은 VM 하나를 두었고, 그 안의 패스를 가리키는 거거든요.


.dockerignore

.dockerignore 파일을 만들어 COPY 하고 싶지 않은 디렉터리 또는 파일을 정할 수 있습니다.

Dockerfile에 따로 어떤 커맨드를 주지 않아도 돼요.

Docker에서 .dockerignore 파일을 찾으면 알아서 이 안에 있는 디렉터리 또는 파일들은 COPY 하지 않습니다.


ARG, ENV

Dockerfile에서 쓸 수 있는 ARG, ENV 커맨드에 대해 알아봅시다.

ARG 커맨드는 Dockerfile에서만 쓸 수 있는 변수를 만듭니다.

만들어 둔 변수는 docker build 커맨드에 --build-arg 옵션을 붙여 쓸 수 있습니다.

ENV 커맨드는 Dockerfile뿐만 아니라 컨테이너에서 돌아가고 있는 애플리케이션 코드에서도 쓸 수 있는 변수를 만듭니다.

Dockerfile에 아래와 같이 쓸 수 있어요.

# PORT가 변수 이름이고 80은 디폴트 값.
ENV PORT 80

docker run 커맨드에 --e(nv) 옵션을 붙여 env들에 대한 값을 붙이면 됩니다.

바란다면 ENV만을 위한 파일을 만들어 둘 수도 있을 겁니다.

흔히 .env 파일을 만들곤 합니다.

그리고 run 커맨드에 --env-file 옵션을 주면 돼요.

profile
Make impacts!

0개의 댓글