728x90
반응형

지금까지의 이미지 & 컨테이너에서는 한 종류의 데이터만 다뤄봤지만 이번엔 볼륨이라는 개념과 함께 다른 종류의 데이터들도 다뤄보는 방법을 알아보겠다.

 

1. 아래 파일을 다운로드 한다.

data-volumes-01-starting-setup.zip
0.01MB

 

npm package들을 다운받고 서버를 실행해보자.

$ npm install
$ node server.js

 

localhost 80번 포트로 웹을 열어보면

 

이런 식으로 화면이 구성 된 것을 볼 수 있다. 서버 파일을 잠시 보면

 

app.post('/create', async (req, res) => {
  const title = req.body.title;
  const content = req.body.text;

  const adjTitle = title.toLowerCase();

  const tempFilePath = path.join(__dirname, 'temp', adjTitle + '.txt');
  const finalFilePath = path.join(__dirname, 'feedback', adjTitle + '.txt');

  await fs.writeFile(tempFilePath, content);
  exists(finalFilePath, async (exists) => {
    if (exists) {
      res.redirect('/exists');
    } else {
      await fs.rename(tempFilePath, finalFilePath);
      res.redirect('/');
    }
  });
});

내가보낸 피드백이 파일 형식으로 저장이 되는 것 또한 볼 수 있다.

 

이제부턴 이 앱을 도커화를 해보자. 먼저 Dockerfile을 만들어준다.

 

/Dockerfile

FROM node:14

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 80

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

 

터미널에서 만든 Dockerfile로 이미지를 빌드한다.

$ docker build -t feedback-node .

 

빌드된 이미지로 run 명령어를 실행한다.

$ docker run -p 3000:80 -d --name feedback-app --rm feedback-node

 

이제는 localhost 3000번 포트에서 사이트를 볼 수 있다.

여기서 피드백을 작성하고 저장을 하면 localhost:3000/feedback/title.txt ( 피드백 제목 )

경로에서 내용을 확인할 수도 있다. ( 서버파일 참조 )

 

하지만 우리는 이미 켜둔 VSCode 프로젝트 안에서는 feedback 폴더 밑에 파일이 생기지 않은 것을 알 수 있다.

이는 당연하겠지만 이미지는 컨테이너를 만드는데에 쓰임이 끝났고, 파일은 격리된 컨테이너에만 생성됐기 때문이다.

 

2. 볼륨이란?

볼륨은 도커에 내장된 기능이며 위에 경우처럼 컨테이너가 삭제될 경우 데이터를 보존할 수 있도록 도와준다.

볼륨은 컨테이너나 이미지에 있는게 아니라 호스트 컴퓨터에 장착된 하드 드라이브에 존재하여 사용가능하거나 컨테이너로 매핑되는 것을 의미한다.

 

3. 컨테이너에 볼륨 적용하기

Dockerfile 파일 안에 VOLUME 을 추가해줄 수 있다.

/Dockerfile

FROM node:14

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 80

# 저장하려는 볼륨
VOLUME ["/app/feedback"]

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

 

이제 다시 이미지를 빌드하고 실행해보자.

$ docker build -t feedback-node:volumes .
$ docker run -d -p 3000:80 --rm --name feedback-app feedback-node:volumes

 

이러고 서버를 실행해보면 

피드백을 작성하고 저장버튼을 누르면 로딩이 되면서 더이상 진행이 안되는 것을 확인할 수 있다. 

로그를 확인해보자.

 

$ docker logs feedback-app

 

/create 라우터를 보면 fs.rename이라는 메소드가 있는데 이 부분을 바꿔준다.

app.post('/create', async (req, res) => {
  const title = req.body.title;
  const content = req.body.text;

  const adjTitle = title.toLowerCase();

  const tempFilePath = path.join(__dirname, 'temp', adjTitle + '.txt');
  const finalFilePath = path.join(__dirname, 'feedback', adjTitle + '.txt');

  await fs.writeFile(tempFilePath, content);
  exists(finalFilePath, async (exists) => {
    if (exists) {
      res.redirect('/exists');
    } else {
      // await fs.rename(tempFilePath, finalFilePath);
      await fs.copyFile(tempFilePath, finalFilePath);
      await fs.unlink(tempFilePath);
      res.redirect('/');
    }
  });
});

 

이제 이미지를 삭제한 뒤 다시 만들고 실행해준다.

$ docker stop feedback-app
$ docker rmi feedback-node:volumes
$ docker rmi feedback-node:volumes
$ docker run -d -p 3000:80 --rm --name feedback-app feedback-node:volumes

 

다시 실행해보면 정상적으로 파일이 읽히는 것을 볼 수 있다.

 

이번엔 컨테이너를 종료하고 파일이 잘 남아있는지 확인해보자.

$ docker stop feedback-app

 

이러고 다시 실행해서 확인해보면 test.txt 가 읽혀지지 않는 것을 볼 수 있다.

 

4. 볼륨의 종류

볼륨의 종류에는 명명된 볼륨, 익명의 볼륨이 있다.

볼륨을 확인하는 명령은 다음과 같다.

$ docker volume ls

 

Dockerfile에서 VOLUME 레이어를 삭제한 뒤 이미지를 재구축하고 다시 실행해보자. 

이 때 run 명령어에 볼륨을 지칭하는 부분을 넣어준다.

$ docker stop feedback-app
$ docker rmi feedback-node:volumes
$ docker rmi feedback-node:volumes
$ docker run -d -p 3000:80 -rm --name feedback-app -v feedback:/app/feedback feedback-node:volumes

 

이러면 컨테이너를 삭제하더라도 볼륨의 데이터가 정상적으로 남아있는 것을 확인할 수 있다.

 

4. 바인드 마운트

우리가 개발한 환경을 이미지화해서 컨테이너를 만들고, 다시 이미지를 수정할 경우 계속 언급해왔듯 변경 사항이 바로 반영이 되지않으므로 이미지를 재구축하고 다시 실행해야 했다. 개발하는 동안에 코드를 수정할 때마다 이 과정을 반복하면 매우 불편하고 시간 소요도 클 것이다. 이것을 바인드 마운트가 도와준다.

 

호스트 컴퓨터의 절대경로로 현재 app이 지정하는 파일 경로를 붙여서 다음과같이 run 을 실행한다. ( 한 줄로 구성된 명령어입니다. )

$ docker run -d -p 3000:80 -rm --name feedback-app -v feedback:/app/feedback
-v "/Users/Desktop/workspace/docker:/app" feedback-node:volumes

 

5. docker volume 명령어들

 

728x90
반응형

+ Recent posts