[Docker] 도커 공식문서로 배우기 (5): Docker Compose
도커 컨테이너는 각 컨테이너가 하나의 기능만 제대로 수행하는 것이 좋습니다. 한 컨테이너가 여러 기능을 담당하는 것은 일반적으로 권장되지 않습니다. 그렇다면 하나의 서비스를 실행하기 위해서는 여러 종속성 컨테이너들 모두에 대해 각각 `docker run` 명령을 실행해야 할까요?
그렇게 해도 되지만 실행 외에도 우리는 할 일이 너무 많습니다. 도커는 그런 상황을 위해 `Compose`를 지원합니다. 이 글은 도커 컴포즈가 무엇인지, 그리고 어떻게 사용하는 지에 대해 다룹니다.
Docker Compose
도커 컴포즈로 우리는 모든 컨테이너와 구성(configuration)을 한 개의 YAML 파일 안에 정의할 수 있습니다. 어떤 프로젝트가 도커 컴포즈로 구성되었다면 아무리 여러 실행 환경을 포함한다 해도, 다른 새 컴퓨터에서도 명령어 한 줄이면 그 프로젝트를 실행할 수 있습니다.
공식 문서는 컴포즈를 '선언적 도구 (declarative tool)'라고 설명합니다.
이 말은, 컴포즈를 작성할 때에는 '어떻게 할지'는 필요하지 않고, 다만 '무엇이 필요한 지'에 대해서만 '선언'하면 된다는 말입니다.
Dockerfile과 Compose의 관계
'한 개의 YAML'이라고 했는데, 이 YAML은 다른 Dockerfile을 (많이) 참조하기도 합니다.
도커파일은 컨테이너의 이미지를 빌드하기 위한 명령을 정의하는 파일입니다.
컴포즈는 컨테이너들을 어떻게 구성하고, 어떻게 실행할 지에 대한 설정 파일입니다.
컴포즈로 컨테이너 올리고 내려보기
git clone https://github.com/dockersamples/todo-list-app
cd todo-list-app
샘플 프로젝트를 복제하고, 프로젝트 루트 디렉토리로 이동합니다.
`compose.yaml`이 보이시나요? 이 파일이 바로 도커 컴포즈 파일입니다.
공식 문서에서는 시간을 들여 구조를 익혀보라했으니, 구조를 한 번 들여다보고 주석을 작성했습니다.
services:
app: # app이라는 서비스를 선언
image: node:18-alpine # 'app'서비스는 노드 이미지를 사용
command: sh -c "yarn install && yarn run dev" # 컨테이너 시작시 실행할 명령
ports:
- 127.0.0.1:3000:3000 # 호스트(127.0.0.1)의 3000번포트를 컨테이너의 3000번 포트로 연결
working_dir: /app # 컨테이너 내 작업 디렉토리를 /app으로 설정
volumes:
- ./:/app # 현재 디렉토리를 컨테이너의 /app에 마운트
environment: # 환경변수 설정, 이하 생략..
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:8.0
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data: # 컨테이너의 데이터 영속성을 위한 저장소(볼륨 생성)
간략하게 정리가 되었다면 이제 `docker compose up -d --build` 명령어를 입력해서 애플리케이션을 시작해보겠습니다.
$ docker compose up -d --build
unable to get image 'mysql:8.0': error during connect: Get "http://%2F%2F.%2Fpipe%2FdockerDesktopLinuxEngine/v1.47/images/mysql:8.0/json": open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.
에러가 납니다.
도커 데스크탑이 꺼져있으면 'unable to get image' 에러를 마주칠 수 있습니다.
도커 데스크탑을 실행하고 다시 시도해보았습니다.
$ docker compose up -d --build
[+] Running 17/17
✔ mysql Pulled 32.6s
✔ 3758af62b8ea Download complete 0.7s
✔ 082df7bb4f09 Download complete 24.3s
✔ 2583e052860a Download complete 0.5s
✔ 8310b139f7c3 Download complete 1.3s
✔ 750e74778c5d Download complete 1.2s
✔ 75d963f8b5a9 Download complete 1.1s
✔ b5f4bc928a89 Download complete 1.6s
✔ f34fb977c6ce Download complete 1.5s
✔ ad9d782f3f87 Download complete 6.9s
✔ acd41a114e50 Download complete 16.5s
✔ a2e746e7b2e3 Download complete 7.9s
✔ app Pulled 20.1s
✔ 25ff2da83641 Download complete 1.0s
✔ 1e5a4c89cee5 Download complete 0.9s
✔ f18232174bc9 Download complete 5.0s
✔ dd71dde834b5 Download complete 15.5s
[+] Running 4/4
✔ Network todo-list-app_default Created 0.1s
✔ Volume "todo-list-app_todo-mysql-data" Created 0.0s
✔ Container todo-list-app-app-1 Started 1.6s
✔ Container todo-list-app-mysql-1 Started 1.3s
잘 실행됐네요!

컴포즈로 올린 컨테이너 삭제
docker compose down
`docker compose down` 명령어로 올렸던 컨테이너를 간단히 삭제할 수 있습니다.
또는 도커 데스크탑의 `Containers`탭에서 GUI를 이용하여 삭제할 수도 있습니다.
