지금까지의 이미지 & 컨테이너에서는 한 종류의 데이터만 다뤄봤지만 이번엔 볼륨이라는 개념과 함께 다른 종류의 데이터들도 다뤄보는 방법을 알아보겠다.
1. 아래 파일을 다운로드 한다.
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 명령어들
'DevOps > Docker' 카테고리의 다른 글
Docker | Docker-Compose (4) | 2022.06.14 |
---|---|
Docker | Network, MongoDB, Node.js, React.js 도커화 명령어 (0) | 2022.06.14 |
Docker | 이미지 & 컨테이너(2) | 관리하기 (0) | 2022.05.31 |
Docker | 이미지 & 컨테이너(1) | 이미지란? (0) | 2022.05.31 |
Docker | 시작하기 (0) | 2022.05.30 |