DevOps/Docker

[Docker] 도커 컴포즈 (Docker Compose)

샤아이인 2022. 9. 29.

 

이번 글 에서는 도커 컴포즈를 통해 좀더 편리하게 컨테이너를 관리해보자!

 

1. Docker Compose

도커 컴포즈는 여러 명령어들을 모아둔 자동화 설정의 명령집합(Orchestration) 입니다.

하나의 명령 집합을 통해 모든 컨테이너를 실행할 수도, 멈출수도 있는거죠!~

 

도커 컴포즈가 Dockerfile을 대신하는 것 은 아니며, 이미지나 컨테이너를 대체하는 것 또한 아닙니다.

또한 여러 host가 있는 상황보다는 단일 host 상황에서 여러 컨테이너를 관리할때 도커 컴포즈가 유용합니다.

 

기본적으로 터미널 상에서 run, build를 할때 옵션으로 주던 모든 명령을 도커 컴포즈를 통해서 사용할 수 있습니다.

 

1 - 1) Docker Compose 버전 추가

우선 도커 컴포즈에서 사용할 버전을 추가해 줍시다.

 

여기서 주의할점이 있는데, 우리 애플리케이션의 버전을 의미하는 것 이 아닙니다.

https://docs.docker.com/compose/compose-file/compose-versioning/

 

Compose file versions and upgrading

 

docs.docker.com

위 글에 나와있듯, 각 컴포즈 버전마다 사용할 수 있는 명령어들이 조금씩 다릅니다.

 

이 글에서는 가장 최신 버전인 3.8 버전을 사용하겠습니다.

version: '3.8'

 

1 - 2) Services

서비스를 통해서 우리의 컨테이너 3개를 추가해봅시다.

version: '3.8'
services:
  mongodb:
  backend:
  frontend:

mongodb, backend, frontend 모두 서비스의 자식입니다.

각각의 컨테이너에 대한 구성사항을 추가해봅시다!

 

▶ mongodb

우선 mongoDB에 대하여 터미널에서 사용했던 명령은 다음과 같습니다.

docker run --name mongodb \
  -e MONGO_INITDB_ROOT_USERNAME=max \
  -e MONGO_INITDB_ROOT_PASSWORD=secret \
  -v data:/data/db \
  --rm \
  -d \
  --network goals-net \
  mongo

 

도커 컴포즈를 사용하면 기본적으로 detach 모드이며, 컨테이너는 중지시 자동 소멸됩니다.

따라서 -d, --rm 은 자동으로 처리되게 되었습니다~

version: '3.8'
services:
  mongodb:
    image: 'mongo'
    volumes:
      - data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=max
      - MONGO_INITDB_ROOT_PASSWORD=secret
  backend:
  frontend:

이미지로는 mongoDB 공식 이미지인 'mongo'를 사용할것을 명시하였습니다.

named volume 또한 지정해주었습니다. 로그파일을 저장하기 위한 용도이죠!

마지막으로는 환경변수를 설정해주었습니다. 다만 환경변수는 직접 위와 같이 명시할수도 있지만, 환경파일.env 파일을 불러와서 사용하도록 할수도 있습니다.

 

네트워크는 따로 설정할 필요가 없습니다.

도커 컴포즈 파일에 등록된 모든 서비스에 대해 새로운 환경을 자동으로 생성하고 모든 서비스를 새로운 네트워크 환경에 추가합니다.

 

만약 네트워크를 추가하고 싶다면 다음과 같이 명시하면 됩니다.

networks:
  - networkName

이렇게 되면 컴포즈가 자동 생성한 네트워크에도 속하고, 위에 명시한 네트워크에도 속하게 되는거죠!

 

또한 Named Volume을 위해서 services 와 같은 계층에 다음과 같이 이름을 추가해줘야 합니다.

volumes:
  data:

이는 Named Volume에서만 필요할뿐, 익명 볼륨과 바인드 마운트의 경우 위와같이 명시해줄 필요가 없습니다.

Named Volume만 명시하면 됩니다.

 

▶ BackEnd

node.js 서버 컨테이너를 위한 터미널에서의 명령어는 다음과 같았습니다.

docker run --name goals-backend \
  -e MONGODB_USERNAME=max \
  -e MONGODB_PASSWORD=secret \
  -v logs:/app/logs \
  -v /Users/shine/study/docker-study/shine-compose/backend:/app \
  -v /app/node_modules \
  --rm \
  -d \
  --network goals-net \
  -p 80:80 \
  goals-node

 

이를 도커 컴포즈로 구성해봅시다!

version: '3.8'
services:
  mongodb:
    image: 'mongo'
    volumes:
      - data:/data/db
    env_file:
      - ./env/mongo.env
    # environment:
    #   - MONGO_INITDB_ROOT_USERNAME=max
    #   - MONGO_INITDB_ROOT_PASSWORD=secret
  backend:
    build: ./backend
    # build:
    #   context: ./backend
    #   dockerfile: Dockerfile
    #   args:
    #     something: 1
    ports:
      - '80:80'
    volumes:
      - logs:/app/logs
      - ./backend:/app
      - /app/node_modules
    env_file:
      - ./env/backend.env
    depends_on:
      - mongodb
  #frontend:

volumes:
  data:
  logs:

우선 이미지를 빌드하기 위해 Dockerfile이 있는 경로를 "build: ./backend"와 같이 추가해주었습니다.

 

또한 ports를 명시하였으며,

 

3개의 volumes 또한 명시하였습니다. 여기서 바인드 마운트가 중요한데, 이전에는 절대 경로를 명시하던 바인드 마운트와 달리, 도커 컴포즈에서는 docker-compose.yml을 기준으로 절대경로로 명시할수가 있습니다.

따라서 "./backend:/app"과 같이 명시하여 사용하겠습니다.

 

환경변수 또한 이전과 달리 "env_file"을 통해 환경변수 파일을 불러와서 사용하도록 변경하였습니다.

 

마지막으로 depends_on 으로 mongodb 서비스를 지정하였는데, 이는 mongodb 컨테이너가 우선 실행된 후, backend 컨테이너를 실행하겠다는 의미입니다. 선후관계를 명시한 것 이죠!

 

다음 명령을 통해 컴포즈 파일을 실행해봅시다!

docker-compose up -d

-d 는 detach 모드로 실행하겠다는 의미 입니다.

처음 로딩될때 보면, 우리가 컴포즈가 자동 생성한 Network가 보입니다.

모든 이름 앞에 prefix로 "shine-compose"가 붙어있는데, 이는 docker-compose.yml 파일이 있는 폴더의 이름 입니다.

 

한가지 의문점이 있습니다. 잠시 우리의 js 파일을 살펴볼까요?

`mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@mongodb:27017/course-goals?authSource=admin`

mongodb에 연결하기 위한 url을 살펴보면 위와 같습니다.

여기서 @mongodb 라고 명시하였는데, 이는 docker-compose 파일에서 우리가 지정한 services자식의 이름입니다.

 

하지만 위에서 보면 컨테이너 이름이 "shine-compose-mongodb-1"로 자동 생성된것을 알 수 있었습니다.

 

과연 우리의 node.js 컨테이너가 mongodb 컨테이너에 연결할 수 있을까요??

=> 예 가능합니다! 서비스의 이름을 우리의 js코드 상에서 사용하면 됩니다!

 

▶ FrontEnd

docker run --name goals-frontend \
  -v /Users/shine/study/docker-study/shine-compose/frontend/src:/app/src \
  --rm \
  -d \
  -p 3000:3000 \
  -it \
  goals-react

이를 컴포즈로 기술하면 다음과 같습니다.

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
  frontend:
    build: ./frontend
    ports:
      - '3000:3000'
    volumes:
      - ./frontend/src:/app/src
    stdin_open: true
    tty: true
    depends_on:
      - backend

volumes:
  data:
  logs:

 

1 - 3) compose 관련 명령어

이후 다음 명령을 통해서 실행해 봅시다!

docker-compose up -d

 

중지하려면 다음과 같이

docker-compose down

 

볼륨까지 삭제하려면 -v 옵션을 추가하면 됩니다.

docker-compose down -v

 

빌드를 강제로 다시 시키고싶은 경우

docker-compose up --build

 

여러 services중 단일 컨테이너만 실행시키고 싶은 경우

docker-compose run mongodb

 

여러 services중 일부 컨테이너만 실행시키고 싶은 경우

docker-compose up mongodb backend

위와 같이 실행하면 frontend 컨테이너는 실행되지 않는다.

댓글