Docker Compose는 다중 컨테이너 도커 application을 정의하고 실행하기 위한 도구이다.
예제를 통해서 한번 알아보자!
간단하게 NodeJS와 Redis를 이용하여 페이지를 새로고침할 때 숫자가 0부터 1씩 올라가는 간단한 앱을 만들어보면서 Docker Compose에 대한 이해를 해보자.
레디스란?
Redis(REmote Dictionary Server)는 메모리 기반의 키-값 구조 데이터 관리 시스템이며, 모든 데이터를 메모리에 저장하고 빠르게 조회할 수 있는 비관계형 데이터베이스(NoSQL)이다.
메모리에 저장을 하기 때문에 DB에 데이터를 저장, 데이터를 불러올때 훨씬 빠르게 처리할 수 있으며, 비록 메모리에 저장하지만 영속적으로도 보관이 가능하여 서버를 재부팅해도 데이터를 유지할 수 있는 장점이 있다.
Docker Compose를 실습할 예정이니 npm init
을 이용하여 기본 뼈대를 만드는 과정은 과감하게 생략.
우선 dependencies에 express 모듈과 redis 모듈을 추가하고 엔트리 포인트를 설정한다.
도커 환경에서 레디스 클라이언트 생성시 주의사항으로는 보통 도커를 사용하지 않는 환경에서는 Redis 서버가 작동되고 있는 곳의 host 옵션을 URL로 위에 처럼 주면 되지만, Docker Compose를 사용할 때는 host 옵션을 docker-compose.yml 파일에 명시한 컨테이너 이름으로 주면 된다.
소스 코드는 다음과 같다.
const express = require("express");
const redis = require("redis");
//레디스 클라이언트 생성
const client = redis.createClient({
socket: {
host: "redis-server",
port: 6379,
},
});
const app = express();
app.get("/", async (req, res) => {
await client.connect();
let number = await client.get("number");
if (number === null) {
number = 0;
}
// console.log("Number: " + number);
res.send("숫자가 1씩 올라갑니다. 숫자: " + number);
await client.set("number", parseInt(number) + 1);
await client.disconnect();
});
app.listen(8080);
console.log("Server is running");
소스 코드를 작성했다면 Dockerfile도 작성해야한다.
// Dockerfile
FROM node:10
WORKDIR /usr/src/app
COPY ./ ./
RUN npm install
CMD ["node", "index.js"]
dockerfile까지 작성이 끝났다면 터미널을 키고 (ide에 built-in 되어있는 터미널을 사용해도 무방하다.) docker built -t <사용자ID/이름> ./
을 입력하여 새로운 이미지를 생성한다.
이제 컨테이너를 하나하나씩 실행할 차례이다. 레디스 클라이언트가 작동하려면 레디스 서버가 켜져있어야 한다.
먼저, 레디스 서버를 위한 컨테이너를 실행하고 NodeJS를 위한 컨테이너를 실행한다.
우선 터미널 2개를 켜서, 하나의 터미널에는 docker run redis
를 입력하여 redis 서버를 킨다.
그리고, 새로 생성해둔 이미지를 실행한다. docker run <사용자ID/이름>
그러나, Redis 서버에 연결할 수 없다는 에러가 뜬다!
이유는 다음과 같다.
서로 다른 컨테이너에 있는데 이러한 컨테이너 사이에는 아무런 설정없이 서로 접근을 할 수 없다. 따라서, NodeJS 앱에서는 레디스 서버에 접근이 불가능하다.
그러면 어떻게 컨테이너 간 통신을 가능하게 만들 수 있을까?
바로 이러한 상황에서 Docker Compose를 이용할 수 있다!
멀티 컨테이너 상황에서 네트워크를 연결해줄 수 있다.
docker compose를 이용하기 위해서는 우선 docker-compose.yml 파일을 만들어야 한다.
yml?
YAML ain't markup language의 약자이며, 일반적으로 구성 파일 및 데이터가 저장되거나 전송되는 응용프로그램에서 사용된다.
원래는 XML이나 json 포맷으로 많이 쓰였지만, 조금 더 사람이 읽기 쉬운 포맷으로 나타낸게 yaml이다.
# docker-compose.yml
version: "3" # docker-compose의 버전
services: # 실행하려는 컨테이너들 정의
redis-server: # 컨테이너 이름
image: "redis" # 사용하는 이미지
node-app: # 컨테이너이름
build: . # dockerfile의 경로, 현 디렉토리에 있는 dockerfile 사용
ports: # 포트 맵핑 (로컬 포트 : 컨테이너 포트)
- "5000:8080"
도커 컴포즈를 이용하기 위해서는 docker-compose up
이라는 명령어를 사용한다.
성공!이 아니라 실패이다. (에러는 빨간색으로 표시해주세요)
Redis를 연결하는데에 있어 에러가 발생한 것 같다.
https://www.npmjs.com/package/redis 읽고 다시 차근차근 해봐야지...오늘은 여기까지