본문 바로가기

STUDY/Docker & Kubernetes: 실전 가이드 -2022년판

11. Docker로 다중 컨테이너 어플리케이션 구축

실습할 어플리케이션

 

여기 Goals 서비스가 있다. 유저는 목표를 추가할 수 있고, 추가된 목표들이 화면에 나타난다. 그리고 추가된 목표를 클릭하여 삭제할 수도 있다. 이 서비스에는 유저가 접속할 Frontend와 목표를 추가하고 제거하는 API가 있는 Backend, 그리고 목표 데이터를 저장한 Database가 필요하다. 이 각각의 요소들을 다중 컨테이너로 구축해보고자 한다.

 

 


컨테이너화

 

어플리케이션은 Database, Backend, Frontend로 구성되어있고 이를 각각 컨테이너로 구성해야한다. Database는 MongoDB로 구동되고 컨테이너가 중지되어도 저장된 데이터는 유지되어야한다. 그리고 Backend에서만 해당 데이터에 접근할 수 있도록 접근 제한이 되어야 한다. Backend는 NodeJS로 만들어진 API 서버가 구동된다. 서버의 로그는 컨테이너가 종료되어도 유지되어야 한다. Frontend는 React SPA로 구성하였다. 개발상의 편의를 위해 로컬의 소스코드 수정이 실행중인 컨테이너에 실시간으로 반영되어야 한다.

 

 


네트워크 생성

 

> docker network create goals-net
> docker network list

 

어플리케이션의 정상적인 동작을 위해서는 Backend 컨테이너와 Database 컨테이너가 서로 통신할 수 있어야 한다. 그리고 컨테이너간의 통신은 도커 네트워크를 사용하는 것이 일반적이다. 그래서 goals-net이라는 도커 네트워크를 생성해주었다.

 


 

mongodb 컨테이너화

 

어플리케이션의 database 컨테이너는 mongodb로 구동하기로 했으므로 dockerhub의 공식 mongo 이미지를 사용한다. 이를위해 dockerhub의 공식 mongo 페이지에서 데이터 유지를 위한 볼륨 경로와 인증을 위한 환경변수 정보를 찾아냈다.

 

> docker run -d --rm --name mongo --network goals-net -v goals-mongo:/data/db -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=secret mongo

mongo이미지를 mongo 이름으로 goals-net 도커 네트워크안에서 실행하였다. 그리고 goals-mongo라는 명명된 볼륨을 /data/db 경로에 적용하였다. 그리고 공식 도커허브 페이지에서 찾은 MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD 환경변수를 설정하였다.

 

 


Backend 컨테이너화

 

 

// Dockerfile 생성
FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 80
ENV MONGO_USERNAME=admin
ENV MONGO_PASSWORD=secret
CMD ["node", "app.js"]

 

// .dockerignore 생성
node_modules
Dockerfile
.git

 

> docker build -t goals-backend .
> docker run -d --rm --name backend --network goals-net -v ${pwd}/logs:/app/logs -p 80:80 goals-backend

Backend 컨테이너는 backend라는 이름으로 database 컨테이너와 통신하기 위해 goals-net 안에서 실행하였다. 또 로그를 보기위해 호스트의 폴더와 컨테이너의 /app/logs 폴더를 바운드 마운트로 연결하였다. 또 API를 요청하기 위해 호스트의 80번포트와 컨테이너의 80번 포트를 연결시켰다.

 

 


Frontend 컨테이너화

 

// Dockerfile
FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

 

// .dockerignore 생성
node_modules
Dockerfile
.git

 

> docker build -t goals-react .
> docker run -d -it --rm --name frontend -v ${pwd}/src:/app/src -p 3000:3000 goals-frontend

Frontend 컨테이너를 frontend라는 이름으로 -it 옵션을 달아서 실행하였다. 호스트에서의 소스 수정이 컨테이너에 반영되도록 컨테이너의 /app/src 경로에 호스트의 소스경로를 바인드 마운트 하였다. 마지막으로 페이지에 접속하기 위한 3000번 포트를 연결하였다.

 

 

728x90