도커 컴포즈
이전에는 호스트 안에서 하나의 컨테이너만 실행했었다. 그런데, 여러 개의 컨테이너를 띄울 수 있는 상황도 생길 수 있다. 조금 더 구체적으로는 서버 애플리케이션 뿐만 아니라 DBMS, 캐시 등을 설정하는 컨테이너도 같이 띄워 관리할 수도 있다.
그런데 컨테이너들이 분산되면 몇 가지 문제가 생길 수 있는데, 대표적으로 일관성의 문제이다. 컨테이너마다 다르게 관리해주어야 하기 때문에 일관성이 깨질 수 있기 때문이다.
이럴 때 사용하는 것이 도커 컴포즈이다!
도커 컴포즈란?
여러 컨테이너를 쉽게 실행할 수 있도록 도와주는 도커 실행 툴이다. 앞서 컨테이너를 띄우려면 많은 옵션을 설정해야 한다. 도커 컴포즈에선 yaml 형식의 설정 파일을 이용하여 여러 개의 애플리케이션 서비스들을 효율적으로 관리할 수 있다. 특히 개발, 테스트, 스테이징 환경을 만드는데 많은 도움을 준다.
크게 3단계로 사용할 수 있다.
1. 애플리케이션이 필요한 환경을 Dockerfile에 정의
2. 애플리케이션 서비스를 위한 설정을 담고 있는 docker-compose.yml 파일을 만든다.
3. docker-compose up 명령을 실행하면 docker-compose-yaml 파일을 읽어서 컨테이너 파일을 만든다.
실습
참고 : www.joinc.co.kr/w/man/12/docker/compose
Docker Compose
어디에 활용 할 수 있을까
www.joinc.co.kr
Flask 애플리케이션을 띄워보자. 설명에 나와있는 대로 설정한 뒤에 docker-compose up을 실행하여 docker ps로 확인해보자.
Flask 애플리케이션이 Redis를 잘 사용하고 있는지도 확인해보자.
어떻게 연결되었을까. 예시에서 link를 사용하여 redis 컨테이너와 연결한 것을 알 수 있다. 이렇게 컨테이너끼리 연결이 되면 포트를 통해 다른 컨테이너로 접속할 수 있는데 app.py의 소스코드에서 6397 포트번호를 통해 접속하는걸 알 수 있다.
이제 여러 개의 컨테이너를 띄워보자.
docker-compose.yml 파일을 위와 같이 수정해주고, web 컨테이너를 3개, redis 컨테이너를 1개 띄워보자.
잘 띄워지는걸 확인할 수 있다. 실전에서 적용하려면 API 게이트웨이 등이 필요할 것이다.
어디에 활용할 수 있는가?
개발 환경
애플리케이션 서버와 DBMS, 캐시 정책은 밀접하게 연관될 수 있다. 요즘엔 이런 것들을 클라우드에 묶어서 배포하곤 하는데, 컴포즈를 사용하면 하나로 통합하여 마치 하나의 서비스처럼 공유하여 동일한 개발환경을 만들 수 있다.
테스트 자동화
CI/CD에서 테스트는 매우 중요하다. MSA 환경에서 다양한 서비스들이 API로 연결될 수 있기 때문에, 배포하려는 서비스 뿐만 아니라 연동되는 다른 서비스들까지도 함께 올려서 테스트를 해야 한다. 컴포즈를 사용하면 테스트에 필요한 애플리케이션들을 동시에 띄워서 테스트할 수 있다.
한계
실 서비스의 경우 서비스를 구성하는 컨테이너들이 원격으로 분리될 수 있다. 하지만 컴포즈는 원격 컨테이너를 조정할 수 있는 기능을 가지고 있지는 않기 때문에 swarm이나 k8s 등의 다른 툴을 이용하여 배포한다.
github.com/docker/awesome-compose/blob/master/react-express-mysql/docker-compose.yaml
docker/awesome-compose
Awesome Docker Compose samples. Contribute to docker/awesome-compose development by creating an account on GitHub.
github.com
예제 분석하기
- networks, secrets, target
- volumes에서 내부 저장소를 연결하지 않은 것들
- /code/node_modules
version : 컴포즈 버전
services : 띄울 서비스
backend : 서비스의 이름
build: 빌드
args: 빌드에 필요한 파라미터 전달
context : 빌드 주체
command : 빌드 명령어
environment : 환경 변수 설정
ports : 포트 설정 (외부 포트 -> 컨테이너 내부 포트로 연결)
volumes : 볼륨 연결 (내부 저장소 : 연결할 외부 저장소)
depends_on : 의존관계 (어떤 컨테이너가 먼저 띄워져야 하는지 설정)
db : 서비스의 이름
image : 베이스가 될 이미지의 이름
command : 전달할 명령어
environment : DB 환경변수 설정