관리 메뉴

코딩하는 락커

섹션 6: Docker Compose: 우아한 다중 컨테이너 오케스트레이션 본문

🐳 도커와 쿠버네티스

섹션 6: Docker Compose: 우아한 다중 컨테이너 오케스트레이션

락꿈사 2022. 7. 26. 17:48

Docker-Compose: 무엇이며 왜 사용하는가?

  • Docker Compose란?
    • 하나의 구성 파일을 사용하여 다수의 docker build와 다수의 docker run 명령을 대체할 수 있는 도구
    • 모든 서비스, 모든 컨테이너를 즉시 시작하고 모든 필요한 이미지를 빌드할 수 있으며 모든 것을 중지할 수 있는 오케스트레이션 명령 셋
    • 구성(Configuration) 파일을 사용하여 단 하나의 명령어로 전체 다중 컨테이너 애플리케이션을 제어할 수 있음
    • 이미지나 컨테이너, 혹은 Docker File을 대체하는 것이 아님
    • 다수의 호스트에서 다중 컨테이너를 관리하는데에는 적합하지 않음. (하나의 동일한 호스트에서 다중 컨테이너를 관리하는데 좋음)

  • Docker Compose File 작성하기
    • 멀티컨테이너 애플리케이션을 구성하는 핵심 구성 요소(Service, 다중 컨테이너를 구성하는 컨테이너)를 작성함
      • 노출 포트
      • 볼륨
      • 환경변수
      • 네트워크

 

 

Compose 파일 만들기

  • Docker Compose.yml 작성
    • mongodb 관련 내용만 일단 작성

# 도커 컴포즈 사양 버전 정의
# 버전은 컴포즈 파일에서 사용하는 기능에 영향을 미침
version: "3.8"
# 컨테이너 이름 정의
# 이름은 원하는대로 작성할 수 있음
# mongodb, backend, frontend 총 3개의 컨테이너가 존재함
services: 
    mongodb:
        # mongodb는 mongo 이미지를 기반으로 함을 알림
        # 기본적으로 detached 모드(종료될 때 자동 제거)로 실행됨
        image: 'mongo'
        # 볼륨 추가
        # -v 태그랑 똑같이 작성
        volumes:
          - data:/data/db
        # mongo.env 파일이 없을 경우 아래처럼 작성할 수 있음
        # enviroment: 
        #   MONGO_INITDB_ROOT_USERNAME = max
        #   MONGO_INITDB_ROOT_USERNAME: max
        #   MONGO_INITDB_ROOT_PASSWORd: secret 
        env_file:
            - ./env/mongo.env
        # 네트워크의 경우 동일한 컴포즈 파일에 정의된 모든 서비스는
        # 이미 도커에 의해 생성됭 동일한 네트워크의 일부가 되므로
        # 네트워크를 지정할 필요가 없음
        # 아래처럼 할 수도 있음
        # networks:
        #   - goals-net
    # backend:
    # frotend: 

# 최상위 볼륨을 지정하여 명명 볼륨 지정
# services에서 사용 중인 명명 볼륨이 나열되어야 함
volumes:
    # mongodb의 volume
    data:
  • ./env/mongo.env 파일 작성

MONGO_INITDB_ROOT_USERNAME=max
MONGO_INITDB_ROOT_PASSWORD=secret

 

 

Docker Compose Up과 Down

  • docker compose 실행
    • 기본적으로 attach 모드로 실행
$ docker-compose up

  • docker compose 실행
    • detached 모드로 실행
$ docker-compose up -d

  • docker compose 실행 중지
    • 모든 서비스 중지, 모든 컨테이너 제거, 디폴트 네트워크 종료
    • 그러나 볼륨은 삭제되지 않음
$ docker-compose down

  • docker compose 실행 중지 & 볼륨 제거
$ docker-compose down -v

 

 

다중 컨테이너로 작업하기

  • Docker Compose.yml 작성
    • backend 관련 내용 작성
version: "3.8"
services: 
    mongodb:
        image: 'mongo'
        volumes:
          - data:/data/db
        env_file:
            - ./env/mongo.env
    backend:
      # backend의 Dockerfile의 위치 작성
      # 도커 컴포즈는 해당 위치의 폴더를 살펴 Dockerfile을 찾아서
      # 이 backend 서비스에 대한 이미지를 빌드함
      # 그리고 빌드가 완료되면 이 컨테이너에 해당 이미지를 사용함
      # 아래 형태도 가능함
      # build:
      #   # Dockerfile의 경로이자 Dockerfile이 빌드되는 장소
      #   # 즉 이미지가 생성되는 장소
      #   context: ./backend
      #   dockerfile: Dockerfile
      #   # Dockerfile에서 ARGS를 사용하는 경우에 사용
      #   args:
      #     some-args: some-value
      build: ./backend
      # 호스트 포트 80을 Node API가 사용하는 내부 포트 80을 연결하여 노출
      ports: 
        - '80:80'
      volumes:
        # 명명 볼륨 추가
        # -v 태그랑 똑같이 작성
        - logs:/app/logs
        # 바인드 마운트 추가
        # 하단에 추가 안해도 됨
        # docker-compose.yml의 상대경로로 작성 호스트의 바인드 마운트 위치 추가
        - ./backend:/app
        # 익명 볼륨 추가
        # 하단에 추가 안해도 됨
        - /app/node_modules
      env_file:
        - ./env/backend.env
      # backend 컨테이너는 mongodb에 연결하므로
      # backend 컨테이너는 이미 실행중인 mongodb 컨테이너에 의존함
      # 따라서 mongodb 컨테이너가 실행된 후에는 backend 컨테이너가 생성하도록 함
      depends_on:
        - mongodb
    # frotend: 

volumes:
    # mongodb의 volume
    data:
    # backend의 volume
    logs:
  • ./env/backend.env 파일 작성
MONGODB_USERNAME=max
MONGODB_PASSWORD=secret
  • docker compose 실행
    • 2개의 컨테이너가 돌고 있는 것을 알 수 있음
    • docker compose가 실제로 할당한 이름은 mongodb, backend가 아님 (compose-01-starting-setup_mongodb_1, compose-01-starting-setup_backend_1로 할당됨)
    • 그러나 services 에서 지정한 이름(mongodb, backend)이 도커에 의해 기억되고, 코드 내에서 이러한 이름으로 네트워크 연결을 설정할 수 있음

 

 

또다른 컨테이너 추가하기

  • Docker Compose.yml 작성
    • frontend 관련 내용 작성
version: "3.8"
services: 
    mongodb:
        image: 'mongo'
        volumes:
          - data:/data/db
        env_file:
            - ./env/mongo.env
    backend:
      build: ./backend
      ports: 
        - '80:80'
      volumes:
        - logs:/app/logs
        - ./backend:/app
        - /app/node_modules
      env_file:
        - ./env/backend.env
      depends_on:
        - mongodb
    frotend: 
      # frontend의 Dockerfile의 위치 작성
      build: ./frontend
      ports:
        - '3000:3000'
      volumes:
      # 바인드 마운트 지정
      # docker-compose.yml의 상대경로로 호스트의 바인드 마운트 위치 추가
        - ./frontend/src:/app/src
      # 이 서비스에 개방형 입력 연결이 필요하다는 것 알림
      # 즉, 인터렉티브 모드를 지정함
      stdin_open: true
      # 터미널에 연결함
      tty: true
      depends_on:
        - backend

volumes:
    data:
    logs:
  • docker compose 실행
    • 이 과정에서 frontend 컨테이너의 코드와 nodejs 종속성과 맞지 않아서 컨테이너 이미지를 지우고 FROM node:16.13.1-alpine으로 dockerfile을 수정하고 다시 재빌드 함 ..

 

 

이미지 빌드 & 컨테이너 이름 이해하기

  • 강제로 이미지 리빌드하기
    • 강제하지 않으면 Dockerfile 기반으로 빌드된 이미지가 한번만 빌드됨
    • 즉 기존 이미지를 재사용함
    • 코드에서 변경된 경우 이 명령어 사용
    • 누락된 이미지를 빌드한 후  컨테이너를 시작하지 않음 (docker-compose up으로 실행해줘야 함)

  • 자체 컨테이너 이름 지정
version: "3.8"
services: 
    mongodb:
        image: 'mongo'
        volumes:
          - data:/data/db
        # 자체적으로 컨테이너 이름 지정
        container_name: mongodb
        env_file:
            - ./env/mongo.env
    backend:
      build: ./backend
      ports: 
        - '80:80'
      volumes:
        - logs:/app/logs
        - ./backend:/app
      env_file:
        - ./env/backend.env
      depends_on:
        - mongodb
    frotend: 
      # frontend의 Dockerfile의 위치 작성
      build: ./frontend
      ports:
        - '3000:3000'
      volumes:
        - ./frontend/src:/app/src
      stdin_open: true
      tty: true
      depends_on:
        - backend
        
volumes:
    data:
    logs:

Comments