도커 컴포즈(Docker Compose)
도커 컴포즈(Docker Compose)
도커 컨테이너로 시스템을 구축하면 하나 이상의 컨테이너가 서로 통신해야 할 때, 그 사이에 의존 관계가 생긴다. 예를 들어 웹 서비스에서 데이터 베이스와 백엔드 서버는 서로 연결되어 동작해야 하는데 각각을 컨테이너로 작성하여 따로 실행하게 되면 관리하기가 힘들다. 이때 필요한 것이 Docker Compose이다. Docker Compose는 여러 개의 도커 컨테이너를 정의하여 한번에 많은 컨테이너를 실행하고 관리할 수 있는 툴이다. docker-compose.yml이라는 파일로 여러 컨테이너에 대한 옵션을 작성하면, docker-compose up이라는 한 번의 명령어로 서비스를 시작할 수 있다.
참고로 docker-compose.yml 파일은 YAML 형식으로 작성한다.
https://bentist.tistory.com/75
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/
https://meetup.toast.com/posts/277
https://www.44bits.io/ko/post/almost-perfect-development-environment-with-docker-and-docker-compose