본문 바로가기

정보/Dev

Docker (3) - 다중 컨테이너를 묶어 정의하기 : docker-compose

 

Docker가 배포, 실행의 차원에서 실행되는 것이라면 여러 개의 이미지를 각각 Dockerfile을 통한 build를 해주어야 하는가?

에 대한 의문이 있다. 물론 2-3개라면 충분히 그럴수 있지만 docker를 통해 더 많은 이미지를 빌드하고, 컨테이너를 일일이 띄워야 하는 작업은 번거로울 수 있다. 여러 개의 container간의 통신이 필요하다면, 각각의 컨테이너별로 host OS를 통한 통신 설정을 해줘야한다.

 

이러한 것을 한꺼번에 설정 해두고 이를 실행해주는 것이 바로 docker-compose이다.

우선, docker-compose에 대해 알아보자.

 

1. docker - compose?

docker-compose란 Dockerfile과 같은 선언형 툴이다. 

Dockerfile.yml은 해당 이미지의 base image를 정의하고, 그 위에 bins, lib를 정의한 후 마지막에 원하는 application을

실행하는 문구로 마무리하는 하나의 컨테이너 실행을 위한 이미지를 정의했다.

docker-compose.yml은 마찬가지로 docker에서 사용하는 설정 파일이지만,

여기서는 단 한 개의 컨테이너가 아닌 여러 컨테이너의 각각의 이미지와 그들간의 설정을 정의하는 파일이다.

 

- 선언형 툴(Declarative Tool)?

선언형 툴이란, 결과를 정의하는 방식을 사용한다. 사용자가 원하는 것을 정의하고, 도구가 자동적으로 결과를 만든다.

사용자가 원하는 "상태"를 선언하고, 그 상태에 맞게 도구가 필요한 동작을 수행하는 것이다.

(다시 곱씹어보니까 상당히 놀라운 기술이다. 필요한 것을 알아서 구현해주는게 쉬운일이 아닐 것 같은데)

Dockerfile이 그랬듯이 말이다. 이번엔 docker-compose.yml의 예시를 살펴보자.

 

2. 예시로 보는 docker-compose

version: "3"
services:
  mysql_container_service:
    container_name: mysql_container
    hostname: mysql_host
    image: mysql:8
    #   image: postgres:15
    #   restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "root"
      MYSQL_USER: "asac"
      MYSQL_PASSWORD: "1234"
      MYSQL_DATABASE: "example"
    #     POSTGRES_USER: "asac"
    #     POSTGRES_PASSWORD: "1234"
    #     POSTGRES_DB: "example"
    ports:
      - 4000:3306
  #     - 6000:5432

  spring_container_service:
    container_name: spring_container
    build: .
    ports:
      - 1000:8080
    environment:
      SPRING_PROFILE: develop
    depends_on:
      - mysql_container_service

위 처럼 되어있을 때, 버전을 명시하고 해당하는 서비스(여러 개의 컨테이너가 담겨진 서비스)를 각각 명시한다.

mysql_container_service:
    container_name: mysql_container
    hostname: mysql_host
    image: mysql:8
    #   image: postgres:15
    #   restart: always

container와 hostname(docker 내부 네트워크에서 DNS의 역할을 한다.)

그리고 사용할 image를 정의한다. 

    environment:
      MYSQL_ROOT_PASSWORD: "root"
      MYSQL_USER: "asac"
      MYSQL_PASSWORD: "1234"
      MYSQL_DATABASE: "example"
    #     MYSQL_USER: "asac"
    #     MYSQL_PASSWORD: "1234"
    #     MYSQL_DB: "example"

이는 mySQL을 사용하는 DB의 환경을 정의한 것이다. 

    ports:
      - 4000:3306
  #     - 6000:5432

이는 포트포워딩이다. 왼쪽의 포트가 host network에서의 port,

오른쪽의 포트가 이 서비스 내부(도커 네트워크 내부에서 사용하는 port)이다.

  spring_container_service:
    container_name: spring_container
    build: .
    ports:
      - 1000:8080
    environment:
      SPRING_PROFILE: develop
    depends_on:
      - mysql_container_service

spring container는 이전과 비슷하다.

build에서 "." 이라는 것은 Dockerfile의 이미지를 사용하라는 것을 의미한다.

여기에 마찬가지로 포트 매핑과 환경 설정, 그리고 의존성이 추가 되어 있다.

 

기존의 Dockerfile에서는 없었고, docker-compose에 있는 것이

port설정, hostname(DNS) 설정, 환경 설정, 의존성 설정 등이 있다.

 

이처럼 설정만 해둔다면, 해당하는 docker-compose 내에서의 통신이 정의되고, 서로 다른 container 사이의 의존성이

정의되고, 환경에 맞춰둔 각각의 이미지들이 알아서 실행되는 상태가 되는 것이 바로 선언형 도구,

docker-compose가 되는 것이다.