도커 컴포즈

변현섭·2023년 12월 21일
0

도커란 무엇인가

목록 보기
8/8
post-thumbnail

1. 개념

1) 필요성

여러 개의 컨테이너로 구성된 시스템을 실행시키는 상황을 생각해보자. 여러 인자와 옵션을 고려해야 하고, 볼륨과 네트워크 설정을 진행해야 하며, 컨테이너와 이미지 목록을 출력해 일일이 삭제해야 하는 수고스러움이 있을 것이다. 이와 같은 상황에서 도커 컴포즈 사용을 고려해볼 수 있다.

도커 컴포즈는 시스템 구축과 관련한 명령어를 하나의 텍스트 파일에 정의함으로써, 명령어 한번으로 시스템 전체를 실행/종료/폐기 할 수 있도록 도와주는 도구이다.

2) 구조

도커 컴포즈는 시스템 구축에 필요한 설정이 정의된 YAML 파일을 이용하여, 시스템을 일괄적으로 실행, 종료, 삭제한다. 사용되는 명령은 도커 명령어와 비슷하지만, 도커 명령어와는 다르다. 도커 컴포즈의 명령은 대표적으로 up 커맨드와 down 커맨드로 구분된다. 다른 커맨드도 있지만, 컨테이너를 종료하는 stop 커맨드 외에는 잘 사용되지 않는다.

① up 커맨드

  • docker run 커맨드와 비슷하다.
  • 정의 파일에 기재된 내용대로 이미지를 내려받고, 컨테이너를 생성 및 실행한다.
  • 네트워크나 볼륨에 대한 설정도 up 커맨드를 이용한다.

② down 커맨드

  • 컨테이너와 네트워크를 정지 및 삭제한다.
  • 이 때, 볼륨과 이미지는 삭제되지 않는다.

③ stop 커맨드

  • 컨테이너와 네트워크를 삭제하지 않고 종료한다.

도커 컴포즈는 텍스트 파일에 정의된 내용을 따라 실행된다는 점에서 이전 포스팅에서 배운 Dockerfile 스크립트와 비슷하다. 하지만, 도커 컴포즈와 Dockerfile 스크립트는 명백히 다른 것이다. 도커 컴포즈는 docker run 커맨드를 여러 개 모아놓은 것과 같은 것으로, 컨테이너 뿐 아니라 네트워크나 볼륨까지 만들어낼 수 있다. 반면, Dockerfile 스크립트는 이미지를 만들기 위한 것이므로, 네트워크나 볼륨을 만들어 낼 수는 없다.

※ 도커 컴포즈와 쿠버네티스
아직 쿠버네티스에 대해 배우지는 않았지만, 도커에 대해 어느 정도 아는 사람이라면 쿠버네티스가 무엇인지 대강 알고 있을 것이다. 쿠버네티스도 여러 개의 컨테이너를 다루기 위해 사용된다는 점에서 도커 컴포즈와 비슷하다고 생각할 수 있는데, 사실 이들의 역할은 명확하게 다르다.
쿠버네티스는 컨테이너 관리를 도와주는 도구인데 반해, 도커 컴포즈는 컨테이너의 생성 및 삭제 정도만 도와주는 도구로써, 컨테이너를 관리하는 기능은 수행하지 않는다.

2. 설치 및 동작 원리

1) 도커 컴포즈 설치

원칙적으로는 도커 컴포즈는 도커 엔진과 별개의 소프트웨어이므로, 도커 엔진을 설치했다 하더라도 도커 컴포즈를 설치해야 한다. 그러나, 윈도우나 macOS에서 사용하는 도커 데스크톱에는 도커 컴포즈가 함께 포함되어 있기 때문에, 실제로 설치할 필요는 없다. 하지만, 리눅스에서 도커를 사용하는 경우에는 도커 컴포즈를 별도로 설치해주어야 한다. 실제 서버를 운영해야 할 때에는 리눅스 OS를 사용해야 하기 때문에, 설치 명령을 알아두는 게 좋다.

리눅스에서 도커 컴포즈를 다운로드 받으려면, 도커 컴포즈와 python3 런타임, python3-pip가 필요하다. 이는 도커 컴포즈가 파이썬으로 작성된 프로그램이기 때문이다. 설치하는 명령은 아래와 같다.

sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose -version // 설치가 잘 되었는지 확인 

도커 컴포즈는 설치와 함께 바로 실행이 가능하므로, 별도의 실행 명령은 존재하지 않는다.

2) 동작 원리

Dockerfile 스크립트를 생성할 때와 비슷하게, 호스트 컴퓨터의 폴더에 YAML 파일을 배치한다. 이 때, 파일의 이름은 반드시 docker-compose.yml이어야 한다. docker-compose.yml의 명령을 실행하려면, 누군가 도커 엔진에 해당 명령을 전달해야 하는데, 이 역할을 도커 컴포즈가 수행한다.

만약 위와 같은 상황에서 도커 컴포즈를 사용하지 않는다면, 각각의 컨테이너에 대해 필요한 명령을 직접 입력했어야 할 것이다. 그러나, 도커 컴포즈를 사용하여 필요한 명령을 미리 정의해두면, 많은 컨테이너에 대해 반복적인 명령을 보다 간편하게 수행할 수 있게 된다.

이 때, 정의 파일은 반드시 한 폴더에 하나만 존재해야 한다. 만약, 여러 개의 정의 파일을 두어야 한다면, 필요한 정의 파일의 수만큼 개별 폴더로 관리하면 된다. 당연히 모든 폴더에서 파일명은 docker-compose.yml로 동일해야 한다.

3. 정의 파일 작성하기

1) 구조 살펴보기

도커 컴포즈는 실행할 정의 파일을 필요로 하기 때문에, 정의 파일 작성법을 알고 있어야 한다. 파일 작성법에 대해 알아보기에 앞서 먼저는, 아래의 예시를 통해 정의 파일의 구조를 살펴보기로 하자. 아래의 예시는 아파치 컨테이너를 생성하는 간단한 정의 파일을 나타낸 것이다. 참고로, yml 파일은 계층 구조로 구성되며, 일반적으로 두 칸의 공백을 이용해 계층을 구분한다. (계층 구분을 위해 tab을 사용하지 않도록 한다.)

version: "3"
services:
  apa000ex1:
    image:httpd
      ports:
        - 8080:80
      restart: always
  • version: 버전 정보, 문자 취급이므로 큰 따옴표로 표기
  • services: 컨테이너 관련 정보
  • restart: 컨테이너가 예기치 않게 종료되었을 때, 시스템이 자동으로 해당 컨테이너를 재시작

정의 파일로 나타내니 다소 복잡하고 낯설게 느껴지지만, 위 내용을 docker run 커맨드로 변경해보면 매우 익숙하게 느껴질 것이다. 아래는 위 정의 파일과 동일한 컨테이너를 생성하는 docker run 커맨드이다.

docker run --name apa000ex1 -d -p 8080:80 httpd

이번에는 조금 더 복잡한 예시를 살펴보기로 하자.

version: "3"
services:
  wordpress000ex1:
    depends_on:
      - mysql000ex1
    image: wordpress
    networks:
      - wordpress000net1
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_HOST=mysql000ex1
      WORDPRESS_DB_NAME=wordpress000db
      WORDPRESS_DB_USER=wordpress000chrome
      WORDPRESS_DB_PASSWORD=pwd
  • depends_on: 서비스 간의 의존성(컨테이너 연동)을 정의
  • network: 네트워크 관련 정보

이와 동일한 docker run 커맨드는 아래와 같다.

docker run --name wordpress000ex1 -dit --net=wordpress000net1 -p 8080:80 -e WORDPRESS_DB_HOST=mysql000ex1 -e WORDPRESS_DB_NAME=wordpress000db -e WORDPRESS_DB_USER=wordpress000chrome -e WORDPRESS_DB_PASSWORD=pwd wordpress

2) 작성 방법

정의 파일도 메모장으로 작성하면 된다. 정의 파일을 작성할 때에는 가장 먼저 정의 파일의 버전을 기입한 후, 상위 계층에서 하위 계층 순으로 작성하는 것이 좋다. 계층 구조는 대략 메인 항목 > 이름 > 설정 순으로 구성된다.

① 메인 항목

  • services, network, volumes 등이 여기에 해당한다.
  • 반드시 콜론을 붙여야 한다.
version: "3"
services:
  # 컨테이너 관련 정보
networks:
  # 네트워크 관련 정보
volumes:
  # 볼륨 관련 정보

② 이름

  • 각 메인 항목에 대해 이름을 정의한다.
  • 이름 뒤에도 반드시 콜론을 붙여야 한다.
version: "3"
services:
  wordpress000ex1:
    # 생략
networks:
  wordpress000net1:
    # 생략
volumes:
  wordpress000vol1:
    # 생략

③ 설정

  • 작성할 내용이 한 가지라면, 콜론 뒤에 이어 적으면 된다.
  • 작성할 내용이 여러 개라면, 들여쓰기 후 하이픈으로 각 내용을 나열한다. (작성할 내용이 한 가지여도 하이픈으로 쓸 수 있다.)
  • 하이픈 뒤에는 한 칸의 공백이 반드시 필요하다.
version: "3"
services:
  wordpress000ex1:
    image: wordpress
    networks:
      - wordpress000net1
    # 이하 생략

3) 정의 파일 작성하기

이제 실제로 정의 파일을 작성하는 실습을 해보기로 하자. 워드프레스 및 MySQL 컨테이너를 생성하는 정의 파일을 작성해보기로 한다. 다만, 이전 실습에서와는 달리 이번 실습에서는 5.7 버전의 MySQL을 사용할 것이며, 볼륨에 대한 정보도 추가할 것이다.

정의 파일을 작성하기 위해 필요한 정보는 아래와 같다.

  • 네트워크 이름: wordpress000net1
  • MySQL 볼륨 이름: mysql000vol11
  • 워드프레스 볼륨 이름: wordpress000vol12
  • MySQL 컨테이너 이름: mysql000ex11
  • 워드프레스 컨테이너 이름: wordpress000ex12
  • 데이터베이스의 이름: wordpress000db

① 폴더 생성하기

  • 정의 파일을 배치할 compose_folder를 c 드라이브 하위로 추가한다.

② docker-compose.yml 파일 생성

  • docker-compose.yml이라는 이름의 파일을 compose_folder 안에 배치한다.

③ 메인 항목 작성

  • docker-compose.yml 파일에 아래의 내용을 입력한다.
version: "3"
services:
networks:
volumes:

④ 이름 작성

version: "3"
services:
  mysql000ex11:
  wordpress000ex12:
networks:
  wordpress000net1:
volumes:
  mysql000vol11:
  wordpress000vol12

⑤ 설정 작성

  • MySQL 컨테이너와 워드프레스 컨테이너의 설정을 동시에 작성하는 것보다는 특정 컨테이너의 설정을 먼저 작성할 것을 권장한다.
  • dpends_on 옵션이 사용되는 컨테이너(여기서는 워드프레스 컨테이너)의 설정을 나중에 작성한다.
version: "3"
services:
  mysql000ex11:
    image: mysql:5.7
    networks:
      - wordpress000net1
    volumes:
      - mysql000vol11:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpwd
      MYSQL_DATABASE: wordpress000db
      MYSQL_USER: wordpress000chrome
      MYSQL_PASSWORD: pwd
  wordpress000ex12:
    depends_on:
      - mysql000ex11
    image: wordpress
    networks:
      - wordpress000net1
    volumes:
      - wordpress000vol12:/var/www/html
    ports: 
      - "8080:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: mysql000ex11
      WORDPRESS_DB_NAME: wordpress000db
      WORDPRESS_DB_USER: wordpress000chrome
      WORDPRESS_DB_PASSWORD: pwd
networks:
  wordpress000net1:
volumes:
  mysql000vol11:
  wordpress000vol12:

파일을 저장하면, 정의 파일 작성이 모두 완료된다.

4. 도커 컴포즈 실행하기

1) 실행하기

도커 엔진에서는 docker 명령을 사용하지만, 도커 컴포즈에서는 docker-compose 명령을 사용한다. up, down, stop 커맨드를 이용해 도커 컴포즈를 실행시켜보자.

① docker-compose up 커맨드

  • 정의 파일의 내용을 따라 컨테이너와 볼륨, 네트워크를 생성한다.
  • 정의 파일의 경로는 -f 옵션을 사용해 지정할 수 있다.
  • 정의 파일이 현재 작업 디렉토리에 위치한다면 파일의 경로를 지정해주지 않아도 된다.
docker-compose -f /compose_folder/docker-compose.yml up -d

② 웹 브라우저를 통해 워드프레스에 접근

  • 주소 창에 localhost:8080을 입력한다.

③ docker-compose down 커맨드

  • 정의 파일의 내용을 따라 컨테이너와 네트워크를 종료 및 삭제한다.
  • 볼륨과 이미지는 삭제되지 않는다. 볼륨과 이미지도 삭제하고 싶다면, --rmi 옵션 과 -v 옵션을 사용하여 관련 볼륨과 이미지를 삭제할 수 있다.
  • 마찬가지로, -f 옵션을 사용해 정의 파일의 경로를 지정할 수 있다.
  • 백그라운드로 실행할 필요가 없다.
docker-compose -f /compose_folder/docker-compose.yml down
// 또는 docker-compose -f /compose_folder/docker-compose.yml down -v --rmi all

2) 주의 사항

도커 컴포즈에는 한 가지 흥미로운 특징이 있다. 도커 컴포즈를 실행한 후 docker ps나 docker volume ls를 입력해보면, 컨테이너와 볼륨의 이름이 우리가 지정한 이름과 조금 달라진 것을 확인할 수 있다.

우리가 지정한 이름의 앞에는 폴더의 이름이 붙고(-f 옵션을 생략한 경우에는 폴더의 이름은 붙지 않는다), 뒤에는 번호가 붙는 형식이다. 이름이 변경되었긴 하지만, 정의 파일에 기재된 컨테이너나 볼륨의 이름은 그대로 사용할 수 있기 때문에, 정의 파일을 수정할 필요는 없다. 다만, 도커 엔진으로 컨테이너를 다뤄야 할 때에는 변경된 이름을 사용해야 한다. 즉, 도커 컴포즈는 자신은 예전 이름을 그대로 사용하면서, 도커 엔진에게는 변경된 이름을 사용할 것을 강요한다.

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

0개의 댓글