볼륨과 바인드 마운트
볼륨
도커는 기본적으로 이미지를 빌드하여 만든 컨테이너는 이미지의 초기값만을 가지고 만들어진다
따라서 해당 컨테이너에서 어떤 작업을하거나 특정 text 폴더를 생성해도 다음번에 이미지로 컨테이너를 빌드하면 결국 데이터가 전부 날아가게 된다.
그래서 있는 기능 중 하나가 volume 이라는 것인데 쉽게 말해 Docker 내 파일과 로컬 환경의 파일을 미러링 시켜주는 기능이다.
익명볼륨이 있고, 명명 볼륨이 있는데 익명 볼륨은 Dockerfile을 통해 생성할수 있고, 컨테이너가 삭제되면 자동으로 삭제된다 (그래서 결국 데이터가 사라짐)
명명 볼륨은 명령어를 통해 생성할수 있고, 컨테이너가 삭제되어도 명명볼륨은 남아있게되어 데이터가 유지되게 한다

-v <볼륨이름>:<도커파일내 경로> 로 볼륨이름(명명) 과 도커 내 경로를 미러링 시킬수 있다
바인드 마운트
볼륨은 도커가 로컬에서 관리하는 파일이었다면, 바인드마운트는 사용자가 관리할수 있는 방식이다.
따라서 로컬에서 편집했을때 도커 내의 파일에 즉각적으로 반영되어 편집하기에 용이하다.
사용하는 방식으론 명령어에 볼륨을 생성할때와 똑같이 사용하는데 단지 절대 경로를 적어주면된다
docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback -v "/Users/jeonghoon/Desktop/FORSTUDY/Docker/data-volumes-03-adj-node-code:/app" docker-node:volumes
위 명령어는 feedback이라는 명명 볼륨을 만들고 내 로컬 절대경로와 docker 내 /app이라는 폴더를 바인드 마운트 시킨것이다. 하지만 여기에는 문제가 생기는데

내 로컬 폴더를 그대로 바인딩하는 문제로 docker build 했을때 컨테이너에 생성되어야 할 node_modules 폴더가 도커 파일(/app) 내에 존재하지 않아서 컴파일이 안되는 것이다.
따라서 /app/node_modules 파일을 미리 볼륨으로 만들어 저장 시켜 놔야하는데 docker volume 생성시 우선순위가 있어서 볼륨을 생성할때 더 폴더 경로가 깊은것을 우선적으로 처리한다고 한다
docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback -v "/Users/jeonghoon/Desktop/FORSTUDY/Docker/data-volumes-03-adj-node-code:/app" -v /app/node_modules docker-node:volumes
따라서 위와 같이 node_modules 에 대한 익명 볼륨을 생성해 주면 문제없이 실행되는것을 볼수 있다
그러면 결론적으로 node_modules 와 feedback 폴더만 볼륨에 의해 독립적으로 관리가 되고 나머지 파일들은 바인드 마운트가 되어 로컬에서 변경하면 도커 내에서도 변경되는 상태가 된다
익명 볼륨은 도커 내부에서 필요한 파일이지만 외부에서 필요없을 때 중간에서 따로 그러한 데이터를 관리하기 용이하게 해주므로 필요한 기능이다
node_modules: 익명 볼륨 (독립적으로 관리, 로컬 변경과 무관)feedback: 명명된 볼륨 (독립적으로 관리, 컨테이너 종료 시 유지)- 나머지: 바인드 마운트 (로컬 ↔ 컨테이너 간 실시간 동기화)

바인드 마운트 읽기 권한
docker run -d -p 3000:80 --rm --name feedback-app -v feedback:/app/feedback -v /app/node_modules -v "/Users/jeonghoon/Desktop/FORSTUDY/Docker/data-volumes-03-adj-node-code:/app:ro" -v /app/temp docker-node:volumes a13c9ab9b128849be13c62491504debaeb536f3f16b55d48fcdbafd53843a1c6
위 명령어를 보면 :ro가 읽기 권한을 뜻한다. 디렉토리에 오직 읽기 권한만 주면 쓰기가 제한되는데 위에서 언급했다시피 깊이가 긴것의 우선순위가 더 높게 책정되어 명명 볼륨으로 선언되어있던 feedback 볼륨은 여전히 기본값인 읽기 쓰기 권한이 있고, 추가적으로 익명 볼륨으로 /app/temp 볼륨만 따로 선언해주면된다. 그리고 temp이름과 같이 임시 볼륨이기떄문에 컨테이너가 삭제되면 자동으로 삭제되는 익명 볼륨과 잘 어울리는것을 알수 있다.
도커에서 환경변수 ENV
세가지 방법 정도가 있다
- Dockerfile에서 ENV 명령어로 설정
FROM node:14
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
ENV PORT 80
EXPOSE ${PORT}
CMD [ "node", "server.js" ]- CLI 옵션에서 환경변수 설정
docker run -d -p 3000:8000 --env PORT=8000 --rm --name feedback-app -v
feedback:/app/feedback -v /app/node_modules -v "/Users/jeonghoon/Desktop/FORSTUDY/Docker/data-volumes-03-adj-node-
code:/app:ro" -v /app/temp feedback-node:env--env 혹은 -e 로 즉석에서 환경변수를 설정할 수 있다.
- CLI 옵션에서 환경변수 파일 설정
docker run -d -p 3000:8000 --env-file ./.env --rm --name feedback-app
-v feedback:/app/feedback -v /app/node_modules -v "/Users/jeonghoon/Desktop/FORSTUDY/Dock
er/data-volumes-03-adj-node-code:/app:ro" -v /app/temp feedback-node:env--env-file./.env 를 통해 환경변수 파일을 지정할수 있다
도커 지역 변수 ARG
FROM node:14
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
ARG DEFAULT_PORT 80
ENV PORT $DEFAULT_PORT
EXPOSE ${PORT}
CMD [ "node", "server.js" ]지역 변수를 사용하여 빌드하면 더 유연하게 이미지를 빌딩할수 있다
예를들어 포트를 따로 초기 빌딩에 세팅하지 않으면 default_port 대로 80으로 포트가 열리는것이고
따로 명령어를 달리하면 다른 포트로 즉시 열리는 식으로 유연하게 처리할 수 있다.
jeonghoon ~/Desktop/FORSTUDY/Docker/data-volumes-03-adj-node-code
docker build -t feedback-app:web-app .
jeonghoon ~/Desktop/FORSTUDY/Docker/data-volumes-03-adj-node-code
docker build -t feedback-app:dev --build-arg DEFAULT_PORT=8000 .