카테고리 없음

[따라하며 배우는 도커와 CI환경] Docker Compose

bona.0 2023. 1. 30. 23:10

본 포스팅은 인프런에서 강의하시는 John Ahn님의 '따라하며 배우는 도커와 CI환경'이라는 강의를 보며

제가 이해한 내용을 정리하는 포스팅입니다. 

 

 

Docker compose란

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

 

Docker compose를 사용해서 어플리케이션을 만들어보자

구현할 어플리케이션 구성:

  • 새로고침 할 때마다 숫자가 1씩 더해지는 기능

  • 두 개의 컨테이너 안에 각각 node.js 앱, 레디스 앱
    • ❔Redis란:
      • 메모리 기반의 키-값 구조의 데이터 관리 시스템. 모든 데이터를 메모리에 저장하고 조회할 수 있는 비관계형 데이터베이스(NoSql)
      • 쓰는 이유: 메모리에 저장을 하기 때문에 MySql같은 디비에 데이터를 저장하는 것과 달리 데이터를 불러올 때 훨씬 빠르게 처리할 수 있음. 메모리에 저장하지만 영속적으로 보관이 가능하고, 서버를 재부팅해도 데이터를 유지할 수 있음.
    • Node.js에서 Redis를 사용하는 방법
      1. redis-server 작동
      2. redis 모듈 다운(package.json에서 dependency의 모듈들)
      3. redis client 생성

Redis client 생성시

  1. 일반 환경에서 레디스 클리이언트 생성시
    레디스 서버가 작동하는 곳이 redis-server.com 이면 호스트 옵션을 다음 처럼 제시.
    레디스 기본 포트: 6379
const client = redis.createClient({
    host: "https://redis-server.com", // 도커환경이 아니면
    port: 6379 // Redis의 기본 포트
})

2. 도커 환경에서 레디스 클라이언트 생성시
도커 compose를 사용할 떄는 host 옵션을 docker-compose.yml 파일에 명시한 컨테이너 이름으로 주면 된다.

//레디스 클라이언트 생성 
const client = redis.createClient({
    host: "redis-server", // 도커환경 일때 레디스 서버가 들어있는 컨테이너의 이름
    port: 6379 // Redis의 기본 포트
})

 

소스코드 작성

  • npm init으로 package.json 생성
    • entry point인 "main" : "server.js"
    • "scripts"에서 "start": "node server.js" 하면 $ npm start run 으로  서버 시작 가능
// package.json
{
  "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": "2.8.0"
  },
  "author": "",
  "license": "ISC"
}
  • server.js
//숫자는 0 부터 시작합니다.
client.set("number", 0); // (키, value)

app.get('/', (req, res) => { // 루트 경로 '/'로 올 때의 동작
    client.get("number", (err, number) => {
        //현재 숫자를 가져온 후에 1씩 올려줍니다.
        res.send("숫자가 1씩 올라갑니다. 숫자: " + number)
        client.set("number", parseInt(number) + 1)
    })
})
  • DockerFile 생성
# 베이스 이미지
FROM node:10 

WORKDIR /usr/src/app

# server.js package.json등의 로컬 파일 복사
COPY ./ ./

# 필요한 종속성들을 package.json의 dependecies의 패키지들 다운
RUN npm install 

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

 

Docker Containers 간의 통신을 위한 Docker Compose

  • 두개의 컨테이너를 별도로 실행시키고 문제 관찰
    순서: 레디스 서버 킨 후, node.js app 실행
    • 레디스 서버 켜기 : $ docker run redis
    • node.js 서버 실행: docker build -t bonapark/docker-compose-app ./
    • 두개의 컨테이너 생성 후, 네트워크를 연결해 주지 않으면 서로 다른 컨테이너의 서버들은 서로 통신할 수 없다.

 

  • 멀티 컨테이너 상황에서 컨테이너간 네트워크 연결을 쉽게 해주는 Docker Compose

 

Docker Compose 파일 작성

  • YAML 파일 형태로 작성됨
version: "3" # 도커 컴포즈의 버전
services: 
  redis-server: # 컨테이너 이름
    image: "redis" # 컨테이너에서 사용하는 이미지
  node-app: # 컨테이너 이름
    build: . # Docker 파일의 경로: 현 디렉토리
    ports: # 포트매핑
     - "5000:8080" # 로컬포트:컨테이너 포트
  • docker-compose up
    -d 옵션: 앱을 백그라운드에서 실행시켜서 터미널에 output을 내놓지 않음
    순서: 이미지 빌드 후 -> 컨테이너 실행
  • docker-compose up vs docker-compose up --build
    • docker-compose up: 이미지가 없을 때만 이미지 빌드하고 컨테이너 시
    • docker-compose up --build: 이미지가 있든 없든 이미지를 빌드하고 컨테이너 시작

  • localhost:5000으로 접속
  • 기본적으로 Docker Compose는 하나의 디폴트 네트워크에 모든 컨테이너를 연결함
    • main.js 파일에서 레디스 클라이언트 생성시 명시했던 호스트의 컨테이너명에 접근할 수 있다(host: "redis-server" )

  • 컨테이너들 한꺼번에 멈추기
    docker-compose.yaml파일이 있는 디렉토리에서 docker-compose down