다중 컨테이너
- DB 서버 (mongoDB)
- 백엔드 서버
- 프론트엔드 서버
다중 컨테이너로 통신해볼까용 ?
Network
docker network create goals-net
MongoDB
docker run -d --name mongo --network goals-net mongodb
Backend (node.js)
// 코드 변경
mongoose.connect(
// localhost -> mongo (mongodb 컨테이너 이름)
'mongodb://mongo:27017/course-goals',
{
useNewUrlParser: true,
useUnifiedTopology: true,
},
(err) => {
if (err) {
console.error('FAILED TO CONNECT TO MONGODB');
console.error(err);
} else {
console.log('CONNECTED TO MONGODB');
app.listen(80);
}
}
);
// Dockerfile
FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 80
CMD ["node", "app.js"]
// docker container build
// frontend 와 통신할 땐 80 포트를 사용할 것임!
docker run -d --rm --name goal --network goal-net -p 80:80 goals-node
Frontend (React)
- 프론트엔드(React) 설정은 node 에 의존해서 React 가 제공하는 개발 서버를 가동한다.
- 브라우저가 이해할 수 있는 코드로 변경한다.
Dockerfile
# 노드가 아니라 리액트 애플리케이션이지만, 노드를 기반으로 동작하기 때문에 노드 이미지를 기반으로 한다.
FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
# 리액트 서버가 사용하는 포트
EXPOSE 3000
# FE package.json 파일 내의 start 스크립트를 실행한다.
# 설치된 종속성 중 하나를 사용하여, 개발 기간동안 리액트를 호스팅하는 개발서버 ㄱㄱ
CMD ["npm", "start"]
command
# -it : interactive mode
# -it : 컨테이너에서 명령을 입력하여 상호작용하는 것이 가능하기를 원한다는 명령을 추가한다.
# 리액트는 이 입력을 받지 않으면 트리거가 되어 서버가 실행되지 않음.
# 실제로 그러진 않을 거지만... :( 그래도 리액트는 이 명령어가 필요하대요~.
docker run --name goals-frontend --rm --network goals-net -p 3000:3000 --network -it goals-react
주의
const response = await fetch('<http://goals-backend/goals/>' + goalId, {
method: 'DELETE',
});
- React 코드는 컨테이너가 아니라 브라우저에서 실행된다.
- 저렇게 goals-backend(백엔드 컨테이너 이름)을 적어도 모름. 도커가 아니니깐.
- 그래서 우리는 브라우저가 이해할 수 있게 적어줘야 함.
바꾸자!
const response = await fetch('<http://localhost/goals/>' + goalId, {
method: 'DELETE',
});
결과
- 3000 포트에서 정상 작동 😊
- 백엔드와도 정상 통신! (mongoDB 에서 데이터 잘 가져오는 중)
볼륨도 사용하자
// 명명볼륨 (이름 data) 사용해서 컨테이너가 없어져도 데이터를 남겨두자 ㅎㅅㅎ
// mongoDB 데이터는 /data/db 디렉토리에 저장됨
docker run --name mongodb --rm -d -v data:/data/db --network goals-net mongo
- 이렇게 하면 컨테이너가 사라져도, 다시 저 볼륨에 연결만 하면 데이터가 보존된다.
보안을 위해 mongoDB 설정을 하자.
// mongoDB 컨테이너에 아이디, 비밀번호 환경 변수를 준다.
docker run --name mongodb --rm -d -v data:/data/db --network goals-net \\n
-e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=root mongo
// backend 애플리케이션에 mongoDB 아이디, 비밀번호를 준다.
// 아이디:비밀번호@호스트 형식 -> root:root@mongodb:27017
// authSource=admin -> 추가 필요
mongoose.connect(
'mongodb://root:root@mongodb:27017/course-goals?authSource=admin',
{
useNewUrlParser: true,
useUnifiedTopology: true,
},
(err) => {
if (err) {
console.error('FAILED TO CONNECT TO MONGODB');
console.error(err);
} else {
console.log('CONNECTED TO MONGODB');
app.listen(80);
}
}
);
백엔드
docker run --name goals-backend \\n
// 실시간 업데이트를 위해 내 컴퓨터와 바인드마운트
-v /Users/holidayk/Desktop/docker-study/multi-01-starting-setup/backend:/app \\n
// 로그파일 저장을 위한 명명 볼륨
-v logs:/app/logs \\n
// 바인드마운트 할 때, 종속성은 덮어씌우지 않기 위해 익명 볼륨으로 막기
-v /app/node_modules \\n
-d --network goals-net -p 80:80 goals-app
백엔드 실시간 코드 업데이트
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1",
"start": "nodemon app.js"
},
"author": "Maximilian Schwarzmüller / Academind GmbH",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"mongoose": "^5.10.3",
"morgan": "^1.10.0"
},
"devDependencies": {
"nodemon": "^2.0.4" // 실시간 업데이트를 위해 nodemon 종속성 추가
}
}
FROM node:10
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 80
ENV MONGODB_USERNAME=root
ENV MONGODB_PASSWORD=secret
# nodemon 사용으로 명령어 변경
CMD ["npm", "start"]
728x90
'개발공부 개발새발 > Docker' 카테고리의 다른 글
Docker ) 유틸리티 컨테이너 (1) | 2024.04.03 |
---|---|
Docker ) Docker-Compose (0) | 2024.04.03 |
Docker ) Network (0) | 2024.03.29 |
Docker ) ARG 와 ENV (0) | 2024.03.18 |
Docker ) 도커 볼륨과 바인드 마운트 (0) | 2024.03.18 |