* yaml 이란?

docker-compose는 yaml 형식을 사용하여 설정 파일을 만들 수 있다. yaml형식은  구조화된 데이터를 표현하기 위한 데이터 포맷. 오픈소스와 nosql에서 많이 사용한다. 또한 파이썬과 같이 들여쓰기로 데이터의 계층 구조를 나타낸다. (들여쓰기는 탭이 아니라 반각 스페이스를 사용한다) 누가 써도 읽기 쉬워서 설정 파일등에 많이 사용된다. yaml에서 데이터 맨 앞에 '-'를 붙이면 배열을 나타낼 수 있다. '-' 다음에는 반드시 반각 스페이스를 넣어야 한다. (반각 스페이스는 우리가 아는 일반 띄어쓰기이다)

 

띄어쓰기와 탭이 매우 중요하며, 명령어옆에 띄어쓰기없이 :과 그다음은 띄어쓰기 후 내용을 작성한다. 이런 식이다. "images: 내용" 또한 계층구조가 중요하다. 띄어쓰기 3개로 구분했다면 띄어쓰기 3개를 해야 같은 계층이 된다. 구문에러가 많이 나는데 보통 띄어쓰기 때문이다.

 

visual studio code 는 docker-compose.yaml작성을 위한 확장파일을 제공한다. 또한 dockerfile 도 지원한다. 가볍게 쓰는데는 노트패드++도 유용하다. 아래처럼 notepad++ 맨 아래 작업 표시줄을 오른클릭하면 언어를 설정할 수 있다.

 

* docker-compose.yml의 기본 형식

총 3개의 요소로 구성된다. 관리하고싶은서비스 (services:) , 네트워크 (networks:) , 볼륨(volumes:) 각 요소의 밑에 추가 상세 설정을 넣을 수 있다. 각 3개의 요소는 모두 명시하지 않아도 된다. 

 

* docker-compose.yml 요소 

 

버전 (version: )

 

상세설명

compose 정의 파일은 버전에 따라 기술할 수 있는 항목이 다르다. 이 버전은 정의파일 맨 앞에 정의한다. 버전을 명시적으로 정의하지 않으면 1.0으로 작동한다. 여러개의 compose 정의 파일이나 확장 서비스를 사용하는 경우는 각 파일에서 동일한 버전을 사용해야 하므로 주의해야 한다.

Compose
정의 파일 버전

Docker
Engine 버전

3.3

17.06.0

3.2

17.04.0

3.1

1.13.1

3

1.13.0

2.3

17.06.0

2.2

1.13.0

2.1

1.12.0

2

1.10.0

1

1.9.1

예시

version: "3"

 

 

이미지 지정 (image: )

 

상세설명

컨테이너의 바탕이 되는 베이스 이미지를 지정한다. 이미지 이름 또는 이미지ID 가 사용된다. 이러한 이미지는 로컬에 있으면 그대로 사용하고, 없으면 도커허브로부터 자동으로 받는다. (도커허브의 모든 이미지 사용 가능) 이미지에 태그가 없으면 latest를 다운받는다.

 

예시

 

 

이미지 빌드 (build: )

 

상세설명

보유하거나 도커허브 이미지를 사용하지 않고 dockerfile로 이미지 작성을 기술하고 그것을 빌드해서 사용하는 경우에 사용한다. 여기에는 도커파일의 경로를 입력한다. 보통 yml 파일과 dockerfile이 같은경로에 있고, 여기에는 현재경로를 의미하는 . 만 입력하게 된다.

 

임의의 이름을 쓰는 경우, dockerfile: 항목을 지정한다. 이 때 dockerfile이 있는 경로나 git 리포지토리 URL을 context: 에 지정할 수 있다. 또한 인수를 지정할 수도 있다. args:  사용한다. args는 환경변수의 값을 정의하며, 해당 인수는 dockerfile에서 ARG로 환경변수 이름을 지정하

 

bool 연산자(true/false/yes/no) 사용하는 경우는 따옴표로 둘러싸야 한다. 환경변수 값은 docker compose 실행하는 머신 위에서만 유효하다.

 

예시

1. /data 저장되어있는 Dockerfile-alternate 라는 이름의 도커파일을 빌드하기

2. 현재 위치에 Dckerfile 빌드하기

3. 인수를 지정하여 Dockerfile 빌드하기

아래와 같이 도커파일에 projectno 변수를 선언하고, docker-compose.yml에서 해당 projectno에 1이란 값을 넣었다. 즉 결과로서 1이 나오게 된다.

vi Dockerfile

FROM centos:7
ARG projectno
RUN echo "$projectno"

 

 

 

컨테이너 안에서 작동하는 명령 지정 (command: , entrypoint: )

 

상세설명

컨테이너에서 작동할 명령은 command: , entrypoint: 로 지정한다. dockerfile의 CMD, ENTRYPOINT와 동일하다. 다만, Dockerfile에 정의되어 있는 것보다 docker-compose에서 정의하는게 더 우선순위가 된다. 즉 CMD, ENTRYPOINT 모두 덮어씌워버린다.

 

예시

Dockerfile에 ENTRYPOINT가 정의되어 있다 하더라도, 아래 docker-compose에서 정의된 대로 작동한다.

 

 

 

컨테이너 간 연결 (link: )

 

상세설명

다른 컨테이너에 대한 링크 기능을 사용하여 연결하고 싶을 때, link를 사용하여 연결할 컨테이너명을 설정한다. 컨테이너명과는 별도로 알리아스명을 붙이고 싶을 때는 '서비스명:알리아스명' 형식으로 지정한다. (아래 예시에서는 db:testdb 이런식으로 할 수 있다) 그런데 이 명령은 도커의 legacy 기능으로, 이제 사용하지 않는 것을 권고한다. 

 

예시

 

 

컨테이너 간 통신 (ports: )

 

상세설명

ports는 컨테이너가 공개하는 포트이다. 즉 호스트OS의 포트와 컨테이너의 포트를 binding 해준다. "호스트포트번호:컨테이너포트번호" 형식으로 지정하거나, 컨테이너의 포트번호만 지정한다. 컨테이너 포트번호만 지정하면, 호스트 포트는 랜덤하게 설정된다.

 

이 명령은 docker-compose up 명령으로 실행할 때만 적용되므로, docker-compse run 명령을 사용하여 실행하는 경우 --service-ports 옵션을 사용해야 한다. 추가로, yaml은 xx:yy 형식을 시간으로 해석하므로 포트번호 설정시 반드시 " " 안에 넣어서 문자열로 정의해야 한다.

 

예시

 

 

컨테이너 간 통신 (expose:)

 

상세설명

호스트 머신에 대한 포트를 공개하지 않고 컨테이너만 포트를 공개한다. 로그 서버와 같이 호스트 머신에서 직접 액세스하지 않고 웹 애플리케이션 서버 기능을 갖고 있는 컨테이너를 경유해서만 액세스 하고 싶은 경우 등에 사용된다. (또는 link 로 연결된 컨테이너↔컨테이너 간의 통신 등에서 사용된다) 그리고, dockerfile에 EXPOSE가 명시되어 있다면 docker-compose에서는 작성하지 않아도 된다.

 

예시

 

 

서비스 의존관계 정의 (depends_on: )

 

상세설명

서비스 간의 의존관계를 지정할 때 사용한다. 예를들어 웹서버 컨테이너를 시작하기 db 컨테이너와 redis 컨테이너를 시작하고 싶을때는 예시와 같이 정의한다. 주의할 점은, depends_on은 컨테이너 시작 순서만 제어할 뿐 컨테이너상 애플리케이션이 이용가능할때까지 기다리고 제어하는게 아니다. 즉 의존관계가 있는 서비스의 준비가 끝날때까지 기다리는게 아니므로 어플리케이션 측에서 대책을 세울 필요가 있다. 다음 링크가 도움이 될 것이다. https://docs.docker.com/compose/startup-order/

 

Control startup and shutdown order in Compose

You can control the order of service startup and shutdown with the depends_on option. Compose always starts and stops containers in dependency order, where dependencies are determined by depends_on, links,...

docs.docker.com

예시

 

 

컨테이너 정보 설정 (container_name: )

 

상세설명

docker-compose 로 생성되는 "컨테이너"에 이름을 붙일 때 사용된다. 예를들어 elasticsearch로 정의한 컨테이너에 elk_m 이라고 이름을 붙이려면 아래 예시대로 한다. 단, 도커 컨테이너명은 고유해야 하므로 커스텀명을 지정하면 여러 컨테이너로 스케일할 수 없어진다.

 

예시

 

 

컨테이너 정보 설정 (labels: )

 

상세설명

label은 컨테이너에 라벨을 붙이는 데 사용한다. 라벨은 여러 목적이 있는데 일반적으로 주석이나 정보등으로써 메타데이터를 만들기 위해 사용한다. yaml 배열 형식 또는 해시형식 중 하나로 지정할 수 있는데, 해시 형식만 예시를 든다. 라벨 확인은 docker-compose config 명령을 사용한다.

 

예시 (2가지)

 

 

컨테이너 환경변수 지정 (environment: , env_file: )

 

상세설명

컨테이너 안의 환경변수를 지정한다. yaml 배열 형식 또는 해시형식 중 하나로 지정할 수 있다. 여기서는 해시 형식만 예를 든다. 설정할 환경변수가 많은 경우다른 파일에서 환경변수를 정의하고  파일을 읽는것이  효과적이다환경변수파일을 읽을때는 env_file:  사용한다. docker-compose.yml 파일과 같은 경로에 envfile 이라는 이름의 파일을 만들고 거기에 환경변수를 넣으면 된다. envfile 많은 경우여러개를 읽을수도 있다파일 지정은 yaml 배열 형식으로 지정한다. 참고로, 애플리케이션 안에서 사용하는 API 키같은 비밀정보의 관리는 컨테이너 오케스트레이션 툴의 기능을 사용하는게 좋다.

 

예시

 

 

컨테이너 데이터 관리 (volumes: , volumes_from)

 

상세설명

컨테이너에 볼륨을 마운트 할 때 사용한다. 호스트 측에서 마운트 경로를 지정하려면, 호스트디렉토리경로:컨테이너디렉토리경로 형식으로 사용한다. 또한 볼륨 지정 뒤에 ro(읽기전용) 등의 옵션을 지정하면 해당 옵션으로 마운트할 수 있다.  ro 옵션은 보통 설정 파일이 저장되거나 수정이 되지 않도록 하는 곳에 지정할 수 있다. 

 

다른 컨테이너가 가진 모든 볼륨을 마운트  때는 volumes_from: 에 해당 컨테이너를 지정한다. 아래 예시처럼 elastic-m 이라는 컨테이너의 볼륨을 그대로 재사용한다.

 

예시 : volumes

예시 : volumes_from

 

+ Recent posts