본문 바로가기
[DevOps]/Docker

Docker로 다중 컨테이너 애플리케이션 구축하기 - 2 (네트워크로 묶기, 데이터 지속성 추가)

by 팡펑퐁 2023. 7. 7.
728x90
지난 글에서 이어진다.

 

 

네트워크 만들기

  • 하나의 네트워크로 연결하기 위해 네트워크를 새로 생성했다.

 

 

네트워크에 데이터베이스 컨테이너 추가

docker run --name mongodb --rm -d --network goals-network mongo

--network 플래그를 사용해서 다시 컨테이너를 실행했다.

 

네트워크에 백엔드 서버 컨테이너 추가

  • 백엔드 서버의 경우 데이터베이스 서버와의 연결을 설정하는 app.js를 수정해야 한다.
  • mongoDB의 컨테이너는 더 이상 외부에 27017 포트를 열지 않는다.
  • 네트워크 통신을 위해 --network 플래그를 사용했기 때문에 'host.docker.internal' 대신 'mongodb'라는 mongoDB의 컨테이너 이름으로 설정하면 된다.
    • 같은 네트워크 안에 넣을 예정이기 때문에 컨테이너 이름으로 해도 알아서 찾는다.

 

  • 위에서 백엔드 서버의 app.js를 수정했으니 이미지를 다시 빌드하고

 

docker run --name goals-backend --rm -d --network goals-network goals-node

  • 기존의 80:80 포트 연결 대신에 네트워크를 추가하여 컨테이너를 실행한다.

 

 

네트워크에 리액트 클라이언트 컨테이너 추가

  • 리액트의 app.js에 있는 api의 ip를 localhost에서 같은 네트워크에 있는 백엔드 서버 컨테이너 명인 'goals-backend'로 바꿔줬다.

 

  • app.js를 수정했으니 다시 리액트 이미지를 빌드하고

 

  • 기존의 3000:3000 포트 연결을 포함하고 네트워크를 추가하여 컨테이너를 실행한다.
  • 로컬 호스트와의 3000 포트 연결을 유지하는 이유는 로컬 호스트에서 리액트 페이지에 접속하여 테스트하기 위해서이다.

 

  • localhost:3000으로 접속하니 에러가 발생했다. 
  • 이유는 간단하다. 리액트 코드는 컨테이너 내부가 아니라 브라우저에서 실행되기 때문이다.

 

  • 즉 내가 브라우저에서 localhost:3000으로 리액트 페이지에 접속했을 때는 브라우저에서 코드가 실행되기 때문에 goals-backend라는 이름의 컨테이너를 찾을 수 없는 것이다.
  • 따라서 리액트 컨테이너는 네트워크 추가가 필요 없고, 백엔드 서버 컨테이너는 로컬 호스트의 브라우저에서 실행 중인 리액트 웹페이지와의 통신을 위해 80번 포트를 열어야 한다.

 

  • docker stop으로 리액트와 node 서버 컨테이너를 삭제한다.(--rm 플래그로 삭제됨)
  • 리액트의 app.js에서 수정한 'goals-backend'를 전부 localhost로 되돌리고 재빌드한다.
  • 그리고 컨테이너를 실행할 때 네트워크를 추가하지 않는다.
    • 어차피 브라우저에서 돌리므로 네트워크 안에 넣을 의미가 없기 때문이다.

 

  • node 서버 컨테이너를 생성하는데 80:80으로 포트를 열어준다.
  • 이렇게 해야 로컬 호스트 머신의 브라우저에서 작동하는 리액트와 컨테이너 내부의 node 서버가 통신할 수 있다.
    • 80번 포트로 통신

 

  • 정상적으로 작동함을 확인할 수 있다.

 

 

데이터베이스 데이터 지속성 추가하기

  • 지금까지는 하나의 네트워크로 연결된 컨테이너 간의 통신을 확인했다.
  • 그런데, 컨테이너를 제거하는 순간 데이터가 컨테이너와 함께 제거되는 문제가 남아있다.
  • 이 문제를 해결해 보자.

 

docker run --name mongodb -v data:/data/db --rm -d --network goals-network -e MONGO_INITDB_ROOT_USERNAME=max -e MONGO_INITDB_ROOT_PASSWORD=secret mongo
  • 데이터의 지속성을 위해 명명된 볼륨을 이용했다.
    • -v로 볼륨을 바로 생성할 수 있다.
    • 볼륨명이 data이다.
    • 명명된 볼륨은 호스트 머신에 저장되는 위치를 알 수 없다.

 

  • mongoDB의 공식 이미지를 보니 컨테이너 안의 mongoDB의 경우 기본값으로 /data/db 경로에 데이터가 저장되는 듯하다.
  • /data/db에 저장되는 데이터를 -v 볼륨 설정으로 로컬 호스트의 어딘가에도 데이터를 저장하는 방식으로 데이터 지속성을 적용한 것이다.
    • -v data:/data/db를 이용하면 컨테이너에 저장되는 데이터(/data/db)가 로컬 호스트 머신(data 위치는 모름)에도 함께 저장된다.
    • -e부터 시작되는 환경변수는 mongDB의 루트 계정 아이디와 비밀번호를 설정한 것이다.(크게 신경 쓰지 말자.)

 

  • 백엔드 서버의 app.js에도 계정 아이디:비밀번호@mongodb 방식과 인증 소스를 적용하기 위해 ?authSource-admin을 사용했다.
  • 이 부분은 도커를 이해하는데 크게 중요하지 않으므로 그냥 넘어가자.
  • 중요한 건 명명된 볼륨으로 데이터의 지속성을 적용했다는 것이다.

 

 

결론

 데이터베이스는 컨테이너가 제거돼도 로컬 호스트에 데이터가 저장되어 있어 언제든지 새로운 컨테이너를 생성하여 기존 데이터를 불러올 수 있고, 네트워크 설정으로 하나의 네트워크에서 백엔드 서버와 데이터베이스 서버가 연결되는 다중 컨테이너 간 통신이 가능하게 되었다.

 

 

참고

Udemy - Docker & Kubernetes : 실전 가이드

728x90