직접 순서대로 각각의 컨테이너를 도커 명령행을 통해 일일이 옵션을 지정해 가며 실행할 수도 잇겠지만, 이런 수동 프로세스는 온갖 실수와 오류의 원천이 되기 쉽다. 직접 시랭하는 과정에 조금만 옵션을 잘못 지정해도 애플리케이션이 정상적으로 동작하지 않거나 컨테이너 간 통신에 문제가 생길 수 있기 때문이다. 이런 방법 대신 도커 컴포즈 파일에 애플리케이션의 구조를 정의하면 된다.
도커 컴포즈 파일은 애플리케이션의 ‘원하는 상태’, 다시 말해 모든 컴포넌트가 실행 중일 때 어떤 상태여야 하는지를 기술하는 파일이다. 또한, docker container run 명령으로 컨테이너를 실행할 때 지정하는 모든 옵션을 한데 모아 놓은 단순한 형식의 파일이다. 도커 컴포즈 파일을 작성하고나면 도커 컴포즈 도구를 사용해 애플리케이션을 실행한다. 그러면 도커 컴포즈가 컨테이너, 네트워크 볼륨 등 필요한 모든 도커 객체를 만들도록 도커 API에 명령을 내린다.
version: '3.7'
services:
todo-web:
image: diamol/ch06-tofo-list
ports:
- "8020:80"
network:
- app-net
network:
app-net:
external:
name: nat
이 스크립트의 내용은 도커 네트워크에 도커 컨테이너 하나가 연결된 간단한 애플리케이션을 기술한 것이다. 도커 컴포즈는 사람도 쉽게 읽고 이해할 수 있으며 (API의 표준 언어인) JSON으로 변환하기도 쉬운 YAML 문법으로 기술된다. YAML 문법은 들여쓰기를 통해 구조를 정의하기 때문에 들여쓰기가 중요하다.
위의 도커 컴포즈 파일은 다음과 같은 세 개의 최상위 문(statement)으로 구성된다.
도커 컴포즈를 사용해 이 애플리케이션을 실행하면 컨테이너 하나가 실행돼 스크립트에 정의된 구성을 갖춘다.
애플리케이션을 직접 실행해 보기 전에 스크립트에서 주의 깊게 살펴볼 부분이 두어 곳 있다. todo-web이라는 이름의 서비스는 diamol/ch06-todo-list 이미지로부터 단일 컨테이너로 실행되며, 이 컨테이너는 호스트 컴퓨터의 80번 포트로 자신의 8020번 포트를 공개한다. 그리고 app-net이라는 이름의 도커 네트워크에 연결된다. 최종적인 결과는 docker container run -p 8020:80 --name todo-web --network nat diamol/ch06-todo-list 명령을 실행한 것과 같은 상태가 된다.
서비스 이름 아래로는 속성이 기술된다. 그 내용이 거의 docker container run 명령의 옵션과 그 지정값의 쌍 형태다. image는 실행할 이미지를 지정하는 필드이고, ports는 공개할 포트에 대한 정보, networks는 컨테이너가 접속할 도커 네트워크를 정의하는 필드다. 서비스 이름은 컨테이너의 이름이자 도커 네트워크상에서 다른 컨테이너들이 해당 컨테이너를 식별하기 위한 DNS 네임으로도 쓰인다. 서비스가 구성될 네트워크 이름은 app-net이다. 그러나 networks 항목을 보면 이 네트워크는 nat이라는 이름의 외부 네트워크로 연결된다. external 필드의 의미는 nat 네트워크가 이미 존재하므로 새로 생성하지 말라는 뜻이다.
도커 컴포즈를 사용하려면 명령행에서 docker-compose 명령을 실행하면 된다. docker-compose의 사용법은 docker 명령과는 다르다. 애플리케이션을 시작하려면 up 명령을 실행해야 한다. 그러면 도커 컴포즈가 컴포즈 파일을 체크하고 애플리케이션을 정의된 상태로 실행하기 위해 필요한 요소를 준비하기 시작한다.
docker network create nat
cd ./ch07/exercises/todo-list
docker-compose up
컴포즈로 애플리케이션을 실행시키기 위해 항상 도커 네트워크가 필요한 것은 아니다. 리눅스 컨테이너를 사용한다면 도커 컴포즈가 네트워크를 대신 관리해 주지만, 윈도 컨테이너를 사용한다면 도커를 설치할 때 자동으로 생성되는 기본 네트워크 nat을 사용해야 한다. 내가 바로 이 nat 네트워크를 사용하도록 했기 때문에 윈도나 리눅스 환경 모두 도커 컴포즈 스크립트가 잘 동작할 것이다.
docker-compose 명령을 실행하면 먼저 현재 작업 디렉터리에서 docker-compose.yml 파일을 찾는다. 해당 파일은 발견하면 to-do 애플리케이션의 정의를 읽어 들인다. 현재는 todo-web 서비스를 구성하는 컨테이너가 하나도 없으므로 도커 컴포즈가 컨테이너를 하나 실행한다. 이때 출력되는 애플리케이션 로그를 컨테이너별로 정리해서 보여 준다. 이 기능은 개발 및 테스트를 수행할 때 매우 도움이 된다.
이제 웹 브라우저에서 http://localhost:8020에 접근해 to-do 애플리케이션의 화면을 띄운다. 도커 컴포즈 파일은 애플리케이션의 소스 코드, Dockerfile 스크립트와 함께 형상 관리 도구로 관리된다. 그리고 이 파일에 애플리케이션의 모든 실행 옵션이 기술된다. 그러므로 README 파일에 애플리케이션 이미지 이름이나 공개해야 할 포트 번호를 문서화할 필요가 아예 없다.
도커 컴포즈 파일 형식에는 애플리케이션의 모든 설정 사항값과 최상위 레벨 도커 요소가 정의된다. 이 애플리케이션은 단일 서비스로 구성되었지만, 이런 경우에도 컴포즈 파일을 통해 설정 사항을 간접적으로 문서화하는 효과를 얻을 수 있다. 하지만 여러 서비스로 구성된 애플리케이션이라면 컴포즈 파일이 꼭 필요할 것이다.