본문 바로가기
도커(Docker)

도커 컴포즈(Docker Compose)

by Bentist 2022. 1. 26.

도커 컴포즈(Docker Compose)

도커 컨테이너로 시스템을 구축하면 하나 이상의 컨테이너가 서로 통신해야 할 때, 그 사이에 의존 관계가 생긴다. 예를 들어 웹 서비스에서 데이터 베이스와 백엔드 서버는 서로 연결되어 동작해야 하는데 각각을 컨테이너로 작성하여 따로 실행하게 되면 관리하기가 힘들다. 이때 필요한 것이 Docker Compose이다. Docker Compose는 여러 개의 도커 컨테이너를 정의하여 한번에 많은 컨테이너를 실행하고 관리할 수 있는 툴이다. docker-compose.yml이라는 파일로 여러 컨테이너에 대한 옵션을 작성하면, docker-compose up이라는 한 번의 명령어로 서비스를 시작할 수 있다.

 

참고로 docker-compose.yml 파일은 YAML 형식으로 작성한다.

https://bentist.tistory.com/75

 

직렬화, XML, JSON, YAML

직렬화(Serialization) 직렬화는 컴퓨터의 데이터 객체를 저장 매체에 저장할 수 있는 형식, 또는 네트워크를 통해 전송할 수 있는 것으로 변환하는 것을 뜻한다. 저장장치에 저장되는 데이터 또는

bentist.tistory.com

docker-compose.yml 작성 기본

# Docker Compose 파일 포맷 버전 지정
version:

# 컨테이너 설정
services:

# 컨테이너에서 사용하는 volume 설정으로 대체 가능(옵션)
volumes:

# 컨테이너간 네트워크 분리를 위한 추가 설정 부분(옵션)
# 보통은 내부 네트워크를 통해 컨테이너간 통신이 이루어지기 때문에 잘 쓰지는 않는다.
networks:

1. version   

도커 컴포즈 파일의 포맷 버전을 지정하는 것이다. Docker 버전에 따라 지원하는 Docker Compose 버전이 있으며, 기본적으로 버전 3을 사용하는 것이 일반적이다. docker-compose는 버전 별로 아래와 같은 특징이 있다.

 

version.1

  • networking이 지원되지 않음
  • 모든 컨테이너는 기본 bridge 네트워크에 배치되고 해당 IP 주소의 다른 모든 컨테이너에서 연결 가능
  • 컨테이너 간 검색을 활성화하려면 links를 사용(version 2, 3에서는 권장하지 않는 방법)

version.2

  • yml 문서에 버전명을 마이너 버전까지 작성 ex) 2.1
  • 모든 각각의 서비스는 services 아래에 다중 컨테이너로 구성
  • volumes에 Named volumes 생성 가능
  • networks에 Network 생성 가능
  • 기본적으로 모든 컨테이너 애플리케이션 전체의 기본 네트워크에 연결되며 서비스 이름과 동일한 호스트 이름에서 검색 가능하다. 이것은 링크가 거의 불필요하다는 것을 의미한다.

버전 2에서 추가된 매개변수 중 중요한 항목은 depends_on인데, 실행 시 depends_on에 명시된 db, redis 컨테이너가 실행된 다음 web 컨테이너가 실행된다. 실행 순서가 중요한 작업에서 유용하게 사용이 가능하다.

depends_on 옵션 컨테이너 실행 순서만 제어할 뿐, 컨테이너의 실행 프로세스 완료 상태까지 제어하는 것은 아니다.

depends_on으로 db 컨테이너가 django 컨테이너보다 먼저 실행되었어도, db의 프로세스 완료 과정이 django보다 길어서 기대한대로 동작하지 않을 수도 있다. 즉, django가 시작되자마자 바로 db 컨테이너에 접속이 안될 수도 있다.

version: "2.4"
services:
  django:
    build:
      context: ./DjangoDocker
      dockerfile: dockerfile_django
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

 

version.3

  • 도커 스웜과 같이 사용되도록 디자인

swarm은 무리, 군중이라는 의미로 Docker swarm은 쿠버네티스를 대신할 도커에서 만든 오케스트레이션 툴이다. 이를 이용하여 여러 호스트 서버의 컨테이너들을 쉽게 관리할 수 있다. 도커 컴포즈단일 호스트에서 여러 컨테이너를 관리한다면, 스웜은 주로 멀티 호스트에서 여러 컨테이너를 묶어서 관리하는 차이가 있다.

2. services

도커 컴포즈를 이용해서 실행할 컨테이너들의 이름과 그 옵션을 정의한다.

2.1) image

컨테이너를 생성할 이미지 정의한다.

ex. web1은 컨테이너 이름을 정의한 것이고, Docker Hub에 있는 이미지를 사용할 경우 image를 설정한다.

아래 코드에서는 httpd이라는 Docker Hub에 있는 이미지를 사용하겠다는 의미이다.

version: "3"

services:
  web1:
    image: httpd

2.2) build

version: "3"

services:
  django:
    build:
      context: ./DjangoDocker
      dockerfile: dockerfile_django

 

build이미지를 도커 파일로 따로 만들어서 사용하는 옵션으로, image 설정 대신 사용한다.

  • context 옵션: 도커 파일이 있는 디렉터리 경로
  • dockerfile 옵션: context 옵션 경로 안에 있는 Dockerfile명

도커 컴포즈 파일이 위치한 폴더 내에 하위 폴더를 생성하여 도커 파일을 관리한다.

2.3) restart

어떤 이유로든 컨테이너가 종료되었을 경우, 재시작을 위한 설정이다.

always : 컨테이너를 수동으로 끄기 전까지 항상 재시작

on-failure : 오류가 있을 시 재시작

version: "3"

services:
  web1:
    image: httpd
    restart: always

2.4) volumes

docker run으로 db 컨테이너를 실행할 때 -v 옵션을 사용하여 데이터베이스 컨테이너의 데이터를 로컬 컴퓨터에 저장했던 것과 같다. docker-compose.yml의 volumes에는 상대 경로를 지정할 수 있어서 편리하다.

여러 volume을 지정할 수 있어서 리스트로 작성한다.

version: "3"

services:
  db:
    image: mysql
    restart: always
    volumes:
          호스트 폴더:컨테이너 폴더
      - "./mysqldata:/var/lib/mysql"
     
# 컨테이너에서 볼륨을 설정했다면, 아래와 같이 volumes에 컨테이너명을 나열해야 한다.     
volumes:
  db:

2.5) environment

Dockerfile의 각종 환경변수를 설정하는 ENV 옵션과 동일하다.

version: "3"

services:
  db:
    image: mysql
    restart: always
    volumes:
      - ./mysqldata:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=1234
      - MYSQL_DATABASE=benn

env_file 옵션으로 환경변수 값이 들어가있는 파일을 읽어올 수도 있다.

패스워드 등의 보안이 필요한 부분을 별도 파일로 작성하여 사용할 때 유용하다.

version: "3"

services:
  db:
    image: mysql
    restart: always
    volumes:
      - ./mysqldata:/var/lib/mysql
    env_file:
      - ./mysql.env

env_file의 파일명을 .txt 등의 확장자로 만들어도 되지만, 도커 공식 가이드에 따라 .env를 쓰는게 좋다.

* mysql.env 파일 포맷

$ cat mysql.env

MYSQL_ROOT_PASSWORD=1234
MYSQL_DATABASE=benn

2.6) port

docker run의 -p 옵션에 해당하는 부분이다. yaml 문법에서 호스트 포트:컨테이너 내부포트으로 작성하면 시간으로 해석하기 때문에 쌍따옴표를 붙여줘야 한다.

version: "3"

services:
  db:
    image: mysql:5.7
    restart: always
    volumes:
      - ./mysqldata:/var/lib/mysql
    env_file:
      - ./mysql.env
    port:
      - "3306:3306"

docker-compose 실행

1) mkdir로 도커 컴포즈 폴더를 별개로 생성한 뒤, vi로 docker-compose.yml을 작성하겠다.

EC2 서버 인바운드 규칙에 3306 포트를 추가하여 외부 IP에서 db에 접근하고자 포트 옵션도 지정

version: "3"

services:
  db:
    image: mysql
    restart: always
    volumes:
      - ./mysqldata:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=1234
      - MYSQL_DATABASE=benn
    ports:
      - "3306:3306"

 

2) docker-compose up -d 를 통해 백그라운드로 실행 -> 현재 작업 폴더에 위치docker-compose.yml 실행

mysql이미지가 이미 있었기 때문에 이미지 설치 없이 바로 mysql 컨테이너가 실행된 것을 확인할 수 있다.

ls를 통해 확인해보면 volumes에서 설정해놓은 mysqldata 폴더가 새로 생긴 것을 알 수 있다.

mysql 컨테이너가 실행되면서 생성된 컨테이너 내부의 데이터베이스와 관련된 var/lib/mysql 내부 파일들이 호스트 PC의 mysqldata 폴더에 연결(바인드 마운트)되어 자동으로 복사되어 있다.

 

3) docker-compose stop 으로 중지

 

4) docker-compose down 으로 docker-compose up으로 생성된 컨테이너 삭제

자동으로 생성되었던 내부 기본 네트워크도 알아서 삭제

 

 

 

참고

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

 

Compose file versions and upgrading

 

docs.docker.com

https://meetup.toast.com/posts/277

 

Docker Compose와 버전별 특징 : NHN Cloud Meetup

도커는 이제 대부분의 개발자 노트북이나 PC에 하나씩은 설치되어있는 필수품이 되어가는데요 편하고 유용한 도커를 좀 더 유익하고 편하게 사용할 수 있는 도구인 Docker Compose에 대해서 알기 쉽

meetup.toast.com

https://www.44bits.io/ko/post/almost-perfect-development-environment-with-docker-and-docker-compose

 

도커(Docker) 컴포즈를 활용하여 완벽한 개발 환경 구성하기

개발 환경을 구축하기란 그리 쉬운 일이 아닙니다. 문서화를 해두어도 누군가 계속 신경쓰지 않으면 내용이 낡기 마련이고, 계속 신경 쓰자니 이 또한 쉽지 않죠. 어떻게 하면 손쉽게 개발 환경

www.44bits.io

 

댓글