본문 바로가기

STUDY/Docker & Kubernetes: 실전 가이드 -2022년판

12. 도커 컴포즈: 다중 컨테이너 오케스트레이션

다중 컨테이너

 

일반적으로 하나의 서비스는 여러 컨테이너로 구성되어있다. 가장 단순한 To-Do 앱을 생각하더라도 사용자가 접속할 화면인 Frontend를 위한 컨테이너, 기능을 수행할 Backend 컨테이너 그리고 데이터를 저장할 database 컨테이너가 필요하다. 그리고 각각의 컨테이너는 상황과 역할에 맞게 컨테이너를 실행해주어야 한다.

 

> docker network create goals-net
> docker run -d --rm --name mongo --network goals-net -v goals-mongo:/data/db -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=secret mongo
> docker build -t goals-backend .
> docker run -d --rm --name backend --network goals-net -v ${pwd}/logs:/app/logs -p 80:80 goals-backend
> docker build -t goals-react .
> docker run -d -it --rm --name frontend -v ${pwd}/src:/app/src -p 3000:3000 goals-frontend

이미지를 만들기 위한 소스들과 Dockerfile은 어쩔수 없다고 하더라도 만들어진 이미지로 컨테이너를 띄우기위한 과정과 명령어들도 매우 복잡하다. 컨테이너간의 통신을 위한 네트워크를 만들어야하고 컨테이너마다 그에 맞는 이름과 네트워크 설정, 볼륨 설정 그리고 환경변수 설정까지 신경써야 할부분이 너무 많다. 그 결과 다중 컨테이너 실행을 위한 명령어는 길어지고 복잡해져서 가독성이 떨어진다.

 

 


도커 컴포즈란

 

도커 컴포즈는 다중 컨테이너 실행해 필요한 설정들을 길고 복잡한 명령어들이 아닌 하나의 구성 파일로 만들어서 다중 컨테이너를 실행할 수 있게 해준다. docker-compose.yaml이라는 설정 파일을 작성해주기만 하면, 도커 컴포즈가 해당 파일을 바탕으로 이미지를 빌드하고 네트워크, 볼륨, 포트, 환경변수까지 설정하여 컨테이너를 실행하고 관리해준다. 다만 도커 컴포즈는 어디까지나 이미지를 위한 소스들과 Dockerfile이 있다는 가정하에 쓰인다. 즉 이미지를 만들기 위한 도구가 아니라 만들어진 이미지를 바탕으로 다중 컨테이너를 구성하는데 특화된 도구이다. 다만 다중 호스트에서의 다중 컨테이너 관리에는 적합하지 않다는 단점이 있다.

 

 


도커 컴포즈 파일 구성

 

version: "3.8"
services:
  backend:
    build: ./backend
    # build: 
    #   context: ./frontend
    #   dockerfile: Dockerfile
    #   args:
    #     - BUILD_ARG=something
    ports:
      - "80:80"
    volumes:
      - ./backend/logs:/app/logs
    depends_on:
      - mongodb

  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/src:/app/src
    stdin_open: true
    tty: true
    depends_on:
      - backend
    

  mongodb:
    image: mongo
    volumes:
      - goals-mongo:/data/db
    # environment:
    #   - MONGO_INITDB_ROOT_USERNAME=admin
    #   - MONGO_INITDB_ROOT_PASSWORD=secret
    env_file:
      - ./env/mongo.env
    # networks:
    #   - goals-net
volumes:
  goals-mongo:

docker-compose.yaml 파일은 위와 같다. 먼저 도커 컴포즈의 버전을 적어주고 바로 서비스들이 나온다. servieces의 하위의 backend, frontend, mongodb는 각각 컨테이너로 띄워진다. backend 서비스는 build를 통해 이미지 빌드를 위한 설정을 해주었다. build는 Dockerfile이 있는 경로만 적어주어도 되고 아니면 상세한 설정으로 경로와 파일명까지 적어줄 수 있다. 그리고 포트와 볼륨을 설정해주었다. 마지막으로 depends_on은 해당 서비스가 띄워진 이후에 backend 서비스를 띄우라는 설정이다. frontend 서비스의 설정은 backend와 거의 유사하다. stdin_open, tty 설정은 입력창이 없으면 꺼져버리는 react의 특성상 들어가있는 설정이다. mongodb는 build대신 바로 image를 가져와서 실행하도록 되어있다. 그리고 env_file을 통해 실행시 필요한 환경변수를 파일로 정의해주었다. 파일 대신 environment로 바로 환경변수를 정의해줄 수도 있다. 그리고 services가 끝난 이후에 서비스들에서 사용된 명명 볼륨의 리스트가 나온다. 이렇게 설정 파일이 끝났다. 여기서 network 설정이 주석처리 되어있는것이 이상해 보일수 있는데, 도커 컴포즈는 하나의 구성파일로 실행되는 컨테이너들을 자동으로 생성한 네트워크 안에서 실행하기 때문에 굳이 새로운 네트워크를 정의할 필요가 없다.

 

 

> docker-compose up -d
> docker ps
> docker-compose down

설정 이후에 docker-compose up 명령어를 통해 실행하면 정의된 서비스들이 3개의 컨테이너로 실행되고있는 모습을 볼 수 있다. 그리고 docker-compose down 명령어로 한번에 모든 컨테이너를 종료시킬 수 있다. 

 

 


도커 컴포즈 빌드

 

> docker-compose up -d --build
> docker-compose build

docker-compose up 명령어는 서비스가 build로 구성되어 있더라고 기존에 빌드된 이미지가 있으면 해당 이미지를 재사용한다. 일반적인 상황에서는 해당 방식이 효율적인 것이 맞지만 소스를 수정했거나 Dockerfile을 수정했다면 이미지를 다시 빌드하여 사용해야 할 것이다. 이때 docker-compose up에 --build 옵션을 붙이거나 docker-compose build 명령어를 수행하여 빌드를 강제할 수 있다.

728x90