2020-10-24

Posted by karais89 on October 24, 2020

인프런에서 결제한 도커 강의 학습 및 내용 정리 진행. 이전에 도커에 대해 몇개의 강의 및 책을 학습한 적은 있어 대략적인 방식만 알고 있는 상태에서, 실제 개발에 적용 가능한지 확인을 위해 학습 중.

섹션 5. Docker Compose

Docker Compose란 무엇인가?

다중 컨테이너 도커 애플리케이션을 정의하고 실행하기 위한 도구

페이지를 리프레쉬 할때 숫자 0부터 1씩 계속 올라가는 간단한 앱을 만들 예정

1
docker-compose up
  • nodejs + redis 사용

어플리케이션 소스 작성하기

1
npm init
  • pakcage.json 만들기 (npm init)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "name": "docker-compose-app",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "express": "4.17.1",
    "redis": "3.0.2"
  },
  "author": "",
  "license": "ISC"
}
  • start 추가 (npm run start)*
  • 디펜던시 추가
1
2
3
4
5
6
const express = require("express");
const redis = require("redis");

const app = express();
app.listen(8080);
console.log('Server is running');

레디스란?

메모리 기반의 키-값 구조 데이터 관리 시스템, 모든 데이터를 메모리에 저장하고 빠르게 조회할 수 있는 비관계형 데이터베이스(NoSQL)이다.

레디스를 쓰는 이유?

메모리에 저장하기 때문에 데이터를 불러올때 훨씬 빠르게 처리할 수 있고, 메모리에 저장하지만 영속적으로도 보관이 가능하다. 서버를 재부팅해도 데이터 유지 가능

nodejs에서 레디스 사용하기

  • redis-server 작동
  • redis 모듈 다운
  • 레디스 클라이언트 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const express = require("express");
const redis = require("redis");

// 레디스 클라이언트 생성
// 도커 환경 host: redis-server (docker-compose yml 파일에 명시한 컨테이너 이름)
// 일반 환경 host: https://redis-server.com
const client = redis.createClient({
    host: "redis-server",
    port: 6379
})

const app = express();

// 숫자는 0 부터 시작합니다.
client.set("number", 0)
app.get('/', (req, res) => {
    client.get("number", (err, number) => {
        // 현재 숫자를 가져온 후에 1씩 증가.
        client.set("number", parseInt(number) + 1)
        res.send("숫자가 1씩 올라갑니다. 숫자: " + number);
    })
})

app.listen(8080);
console.log('Server is running');

Dockerfile 작성하기

nodejs를 위한 도커파일 작성. 이전에 작성한것과 똑같이 작성

1
2
3
4
5
6
7
8
9
FROM node:10

WORKDIR /usr/src/app

COPY ./ ./

RUN npm install

CMD ["node", "server.js"]

Docker Containers간 통신 할 때 나타나는 에러

레디스 클라이언트가 실행되려면 레디스 서버가 구동되어야 함.

레디스 서버를 다른 컨테이너에 켜놓아야 함.

1
2
docker build 도카아이디/앱이름.
dcker run -p 5000:8000 이미지 이름
1
2
3
4
docker run redis

docker build -t karais89/docker-compose-app ./
docker run karais89/docker-compose-app
  • 에러 발생

    Error: Redis connection to redis-server:6379 failed - getaddrinfo ENOTFOUND redis-server redis-server:6379 at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)

서로 다른 컨테이너에 있는데 이렇게 컨테이너 사이에는 아무런 설정없이는 접근을 할 수 없다.

멀티 컨테이너 상황에서 쉽게 네트워크를 연결시켜주기위해서 Docker Compose를 이용하면 된다.

Docker Compose 파일 작성하기

  • docker-compose.yml 파일 작성

yaml 파일은 이전에 파일 작성시 xml, json 포맷으로 많이 쓰였지만 , 좀 더 사람이 읽기 쉬운 포맷으로 나타낸 파일.

구조

  • version → 도커 컴포즈 버전
  • services → 이곳에 실행하려는 컨테이너들을 정의
    • redis-server → 컨테이너 이름
      • image → 컨테이너에서 사용하는 이미지
    • node-app → 컨테이너 이름
      • build → 현 디렉토리에 있는 Dockerfile 위치
      • ports → 포트 맵핑
1
2
3
4
5
6
7
8
version: "3"
services:
    redis-server:
        image: "redis"
    node-js:
        build: .
        ports:
            - "5000:8080"

실행

1
2
docker-compose up
docker-compose up --build

Docker Compose로 컨테이너를 멈추기

1
docker-compose down
1
2
3
4
docker-compose up -d --build
docker ps
docker-compose down
docker ps
  • d 옵션 detatch 모드
  • build 옵션 이미지가 있든 없든 무조건 빌드