도커 컴포즈는 다음과 같이 정의할 수 있다.
- 시스템 구축과 관련된 명령어를 하나의 텍스트 파일(정의 파일)에 기재해 명령어 한번에 시스템 전체를 실행하고 종료와 폐기까지 한 번에 하도록 도와주는 도구.
- 시스템 구축에 필요한 설정을 YAML(YAML Ain’t a Markup Language) 포맷으로 기재한 정의 파일을 이용해 전체 시스템을 일괄 실행(run) 또는 일괄 종료 및 삭제(down)할 수 있는 도구다.
본래 도커 엔진과 별개의 프로그램으로 존재했지만(구버전. docker-compose로 실행) 도커 측에서 도커 엔진을 설치할 때 도커 컴포즈도 패키지로 같이 설치되도록 방침을 바꾸었다(신버전. docker compose로 실행). 따라서 별도의 파일을 설치할 필요는 없다.
dcoker-compose.yml
컴포즈 파일의 이름은 미리 정해진 docker-compose.yml이라는 이름을 사용해야 한다.
정의 파일은 한 폴더에 하나만 있을 수 있다.
정의 파일의 작성
정의 파일은 YAML 형식을 따른다.
정의 파일에는 services와 networks, volumes를 기재할 수 있다.
서비스와 컨테이너
도커 컴포즈에서는 컨테이너가 모인 것을 ‘서비스’라고 부른다.
공식 참조 문서에서는 컨테이너와 서비스라는 두 가지 용어가 함께 사용되는데, 그냥 모두 컨테이너로 이해하면 되므로 큰 문제는 없다.
컴포즈 파일의 주항목
| 항목 | 내용 |
|---|---|
| services | 컨테이너를 정의한다. |
| networks | 네트워크를 정의한다. |
| volumes | 볼륨을 정의한다. |
services의 정의 내용(자주 쓰이는 것)
| 항목 | docker run 커맨드에서 대응되는 옵션 또는 인자 | 내용 |
|---|---|---|
| image | 이미지 인자 | 사용할 이미지를 지정 |
| networks | —net | 접속할 네트워크를 지정 |
| volumes | -v, —mount | 스토리지 마운트를 지정 |
| ports | -p | 포트 설정 |
| environment | -e | 환경변수 설정 |
| depends_on | 없음 | 다른 서비스에 대한 의존관계를 정의 |
| restart | 없음 | 컨테이너 종료 시 재시작 여부를 설정 |
depends_on: 은 다른 서비스에 대한 의존 관계를 나타낸다. 컨테이너를 생성하는 순서를 정의할 수 있다. 예를 들어, penguin 컨테이너의 정의에depends_on - namgeuk- 라는 내용이 포함되어 있다면 namgeuk 컨테이너를 생성한 다음에 penguin 컨테이너를 만든다.
restart: 컨테이너 종료 시 재시작 여부를 설정한다.
restart 설정 옵션
| 설정값 | 내용 |
| -------------- | --------------------------------------------------- |
| no | 재시작하지 않는다. |
| always | 항상 재시작한다. |
| on_failure | 프로세스가 0 이외의 상태로 종료되었다면 재시작한다. |
| unless_stopped | 종료 시 재시작하지 않음. 그 회에는 재시작한다. |
services의 정의 내용(자주 쓰이지 않는 것)
| 항목 | docker run 커맨드에서 대응되는 옵션 또는 인자 | 내용 |
|---|---|---|
| command | 커맨드 인자 | 컨테이너 시작 시 기존 커맨드를 오버라이드 |
| container_name | —name | 실행할 컨테이너의 이름을 명시적으로 지정 |
| dns | —dns | DNS 서버를 명시적으로 지정 |
| env_file | 없음 | 환경설정 정보를 기재한 파일을 로드 |
| entrypoint | —entrypoint | 컨테이너 시작 시 ENTRYPOINT 설정을 오버라이드 |
| external_links | —link | 외부 링크를 설정 |
| extra_hosts | —add-host | 외부 호스트의 IP 주소를 명시적으로 지정 |
| logging | —log-driver | 로그 출력 대상을 설정 |
| network_mode | —network | 네트워크 모드를 설정 |
build
build 항목에 정의된 컨텍스트 디렉토리에서 이미지를 빌드해 서비스의 컨테이너를 생성하도록 설정한다. image 항목을 기재한다면, build한 이미지의 이름은 image 항목에 기재된 것이 된다. 만약 image 항목을 기재하지 않는다면, 이미지의 이름은 [프로젝트 이름]:[서비스 이름]이 된다.
또한 build 항목에서는 도커 파일에 사용될 컨텍스트나 도커 파일의 이름, 도커 파일에서 사용될 인자 값을 설정할 수 있다.
services:
web:
build: ./composetest
context: ./composetest
dockerfile: myDockerfile
args:
HOST_NAME: web
HOST_CONFIG: self_configextends
networks의 정의
driver
도커 컴포즈는 생성된 컨테이너를 위해 기본적으로 브리지 타입의 네트워크를 생성한다. 그러나 YAML 파일에서 driver 항목을 정의해 서비스의 컨테이너가 브리지 네트워크가 아닌 다른 네트워크를 사용하도록 설정할 수 있다. 특정 드라이버에 필요한 옵션은 하위 항목인 driver_ops로 전달할 수 있다.
다음 예제는 docker-compose up -d 명령어로 컨테이너를 생성할 때 mynetwork라는 overlay 타입의 네트워크도 함께 생성하고, myservice 서비스의 네트워크가 mynetwork 네트워크를 사용하도록 설정한다. 단, overlay 타입의 네트워크는 스웜 모드나 주키퍼를 사용하는 환경이어야만 생성할 수 있다.
services:
myservice:
image: nginx
networks:
- mynetwork
networks:
mynetwork:
driver: overlay
driver_opts:
subnet: "255.255.255.0"
IPAdress: "10.0.0.2"ipam
external
볼륨의 정의
driver
external
도커 컴포즈는 YAML 파일에서 volume, volumes-from 옵션 등을 사용하면 프로젝트마다 볼륨을 생성한다. 이때 external 옵션을 설정하면 볼륨을 프로젝트를 생성할 때마다 매번 생성하지 않고 기존 볼륨을 사용하도록 설정한다.
다음 예제에서 myvolume이라는 이름의 외부 볼륨을 web서비스의 컨테이너에 마운트한다.
volumes:
myvolume:
external: true예제
services:
mysql000ex11:
image: mysql:5.7
networks:
- wordpress000net1
volumes:
- mysql000vol11:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: myrootpass
MYSQL_DATABASE: wordpress000db
MYSQL_USER: wordpress000kun
MYSQL_PASSWORD: kunpass
wordpress000ex12:
depends_on:
- mysql000ex11
image: wordpress
networks:
- wordpress000net1
volumes:
- wordpress000vol12:/var/www/html
ports:
- 8080:80
restart: always
environment:
WORDPRESS_DB_HOST: mysql1000ex11
WORDPRESS_DB_NAME: wordpress000db
WORDPRESS_DB_USER: wordpress000kun
WORDPRESS_DB_PASSWORD: wkunpass
networks:
wordpress000net1:
volumes:
mysql000vol11:
wordpress000vol12:
도커 컴포즈 커맨드
모든 docker compose 커맨드는 docker compose로 시작한다.
현재 작업 디렉토리에 도커 컴포즈 파일이 있다면 그냥 사용한다.
그렇지 않다면, -f 옵션으로 컴포즈 파일의 경로를 지정하여야 한다.
docker-compose -f <도커 컴포즈 파일 경로> command <옵션 ...>
up
docker run 커맨드와 유사하다.
정의 파일에 기재된 내용대로 이미지를 내려받고 컨테이너를 생성 및 실행한다. 정의 파일에는 네트워크나 볼륨에 대한 정의도 기재할 수 있어서 주변 환경을 한꺼번에 생성할 수 있다.
| 옵션 | 내용 |
|---|---|
| -d | 백그라운드로 실행 |
| —build | 컨테이너를 실행하기 전에 이미지를 빌드 |
docker compose up 명령어의 끝에 서비스의 이름을 입력해 docker-compose.yml 파일에 명시된 특정 서비스의 컨테이너만 생성할 수 있다.
docker compose up <도커 컴포즈에서 정의된 서비스 이름>
run
docker compose run 명령어로 컨테이너를 생성할 수도 있다. docker compose up과의 차이점은 Interactive 셸을 사용할 수 있다는 것이다.
down
정의 파일에 기재된 컨테이너와 네트워크를 정지 및 삭제한다. 볼륨과 이미지는 삭제하지 않는다. 컨테이너와 네트워크 삭제 없이 종료만 하고 싶다면 stop 커맨드를 사용한다.
| 옵션 | 내용 |
|---|---|
--rmi <종류> | 삭제 시에 이미지도 삭제한다. 종류를 all로 지정하면 사용했던 모든 이미지가 삭제된다. local로 지정하면 커스텀 태크가 없는 이미지만 삭제한다. |
-v ,--volumes | volumes 항목에 기재된 볼륨을 삭제한다. 단, external로 지정된 볼륨은 삭제되지 않는다. |
stop
정의 파일에 기재된 컨테이너를 정지한다.
config
docker-compose.yml 파일의 포맷이 적절한지 검사한다.
기본적으로 현재 디렉토리의 docker-compose.yml 파일을 검사한다.
docker compose config
아래와 같이 검사할 파일의 경로를 설정할 수 있다.
docker compose -f <yml 파일 경로> config
scale
도커 컴포즈 파일에 기재된 서비스를 여러 개 복제하는 명령어이다.
docker compose scale <도커 컴포즈 파일에 명시된 서비스 이름>=<복제하고자 하는 개수>
예를 들어 도커 컴포즈 파일에 mysql이라는 서비스가 정의되어 있다면, 다음의 명령어를 통해 mysql 컨테이너 4개를 한 번에 만들 수 있다.
docker compose scale mysql=4
도커 컴포즈 네트워크
YAML 파일에 네트워크 항목을 정의하지 않으면 도커 컴포즈는 프로젝트 별로 브리지 타입의 네트워크를 생성한다. 생성된 네트워크의 이름은 {프로젝트 이름}_default로 설정되며, docker compose up 명령어로 생성되고 docker-compose down 명령어로 삭제된다.
서비스 내의 컨테이너는 —net-alias가 서비스의 이름을 갖도록 자동으로 설정되므로 이 네트워크에 속한 컨테이너는 서비스의 이름으로 서비스 내의 컨테이너에 접근할 수 있다.
예를 들어, web 서비스와 mysql 서비스가 각기 존재할 때 web 서비스의 컨테이너가 mysql이라는 호스트 이름으로 접근하면 mysql이라는 호스트 이름으로 접근하면 mysql 서비스의 컨테이너 중 하나의 IP로 변환(resolve)되며, 컨테이너가 여러 개 존재할 경우 라운드 로빈으로 연결을 분산한다.
도커 컴포즈의 프로젝트
도커 컴포즈는 컨테이너를 프로젝트 및 서비스 단위로 구분하므로 컨테이너의 이름은 일반적으로 다음과 같은 형식으로 정해진다.
[프로젝트 이름]_[서비스 이름]_[서비스 내에서 컨테이너의 번호]
도커 컴포즈는 기본적으로 docker-compose.yml 파일이 위치한 디렉터리의 이름을 프로젝트 이름으로 사용한다. 하지만 다음과 같이 -p 옵션을 사용해 프로젝트의 이름을 명시하고 명령어를 적용할 대상(=프로젝트)를 지정할 수 있다
docker compose -p <project_name> <cmd> <option>
하나의 프로젝트는 여러 개의 서비스로 구성되고, 각 서비스는 여러 개의 컨테이너로 구성된다. 더 나아가, 하나의 서비스에는 컨테이너의 복사본 여러 개가 포함되어 있을 수 있으므로(ex. 서버 컨테이너를 여러 개 올려 부하를 분산한다던가) 차례대로 증가하는 컨테이너의 번호를 붙여 서비스 내의 컨테이너를 구별한다.
ubuntu_mysql_1, ubuntu_mysql_2, ..., ubuntu_mysql_n
컨테이너의 복제품을 만드는 방법은 앞선 도커 컴포즈 커맨드 단락에 기술되어 있다.
참고자료