도커 - 도커 컴포즈

지금까지 우리는 하나의 컨테이너만 가지고 실습을 진행했어요. 사용했던 도커의 옵션도 아직은 그리 많지 않았죠?

그런데 나중에 여러 컨테이너를 관리하거나 복잡한 옵션을 사용하게 된다면, 내가 어떤 명령어로 컨테이너를 실행했었는지 금방 잊어버리게 될 거예요.

예를 들어 다음의 명령어를 실행한 적이 있다고 가정해 보세요.

docker run \
  --name my-complex-nginx \
  -p 8080:80 \
  -p 8443:443 \
  -v /host/path/to/nginx/conf:/etc/nginx/conf.d:ro \
  -v /host/path/to/nginx/html:/usr/share/nginx/html \
  -v /host/path/to/nginx/logs:/var/log/nginx \
  -e NGINX_WORKER_PROCESSES=auto \
  -e NGINX_CLIENT_MAX_BODY_SIZE=20M \
  --network my_custom_backend_network \
  --restart unless-stopped \
  --cpus="1.5" \
  --memory="512m" \
  --log-driver="json-file" \
  --log-opt max-size="10m" \
  --log-opt max-file="3" \
  --user 1001:1001 \
  --read-only \
  --dns 8.8.8.8 \
  --dns 8.8.4.4 \
  nginx:latest \
  nginx -g 'daemon off;'

나중에 이렇게 실행했던 명령어가 다시 필요해서 기억해야 한다면 머리가 아파오지 않을까요?

이렇듯, 명령어만으로 복잡한 옵션의 많은 컨테이너를 관리하는 건 쉽지 않아요. 그래서 도커에서는 이 문제를 해결하기 위해 컴포즈(Docker Compose) 라는 플러그인을 제공하고 있어요.

이 플러그인을 사용하면 컨테이너가 어떻게 실행되어야 하는지를 미리 문서로 작성해 두고, 이를 한번에 반영할 수 있게 돼요. 덕분에 컨테이너 관리가 많이 편해지게 될 거예요.


컴포즈 파일 작성하기

이제부터는 이전에 명령어로 배포한 Memos 컨테이너를 도커 컴포즈를 통해 다시 배포하게 될 거예요. 그러니 Memos 컨테이너를 구동 중이라면 다음의 명령어를 통해 제거해 주세요.

docker stop memos
docker rm memos

이제 시작해 볼까요?

도커 컴포즈 파일을 작성하기 위해서는 먼저 docker-compose.yml이라는 파일을 만들어야 해요.
다음의 명령어를 통해 원하는 곳에 docker-compose.yml 파일을 생성해 주세요.

touch docker-compose.yml

그 다음엔 텍스트 에디터를 통해 docker-compose.yml 파일을 열어주세요.
터미널 가이드에서 소개해드렸던 nano 에디터를 사용하시면 돼요.

nano docker-compose.yml

에디터가 열리면 다음의 내용을 복사해서 붙여넣고 저장 후 닫아주세요.

services:
  memos:
    image: neosmemo/memos:stable
    container_name: memos
    volumes:
      - ~/.memos/:/var/opt/memos
    ports:
      - 5230:5230

여기서 작성한 내용을 조금 살펴볼게요.

graph BT;
services;
memos;
image;
container_name;
volumes;
ports;

image --> memos;
container_name --> memos;
volumes --> memos;
ports --> memos;
memos --> services

도커 컴포즈 파일은 YAML 이라는 작성 규칙을 가지고 있어요. 이를 간략하게 설명 드리자면, 들여쓰기(공백)을 통해 데이터의 부모, 자식 상관관계를 나타내는 문법이에요.

최상위에는 들여쓰기가 없는 services 가 있고, servicesmemos라는 자식이 있으며, memosimage, container_name, volumes, ports 라는 자식이 있다고 읽을 수 있어요.

도커 컴포즈에서는 실행하고 싶은 컨테이너를 services 하위에 작성해야 해요. 그래서 먼저 memos 라는 자식을 선언했어요. 그 다음에는 사용하고 싶은 컨테이너의 옵션들을 이 하위에 넣어주면 돼요.

이번에는 Memosdocker run 으로 배포했을 때 명령어와 비교해서 살펴볼게요.

docker run -d \
  --name memos \                  # 컨테이너 이름
  -p 5230:5230 \                  # 포트 포워딩 옵션
  -v ~/.memos/:/var/opt/memos \   # 볼륨 마운트 옵션
  neosmemo/memos:stable           # 사용할 이미지 이름
services:
  memos:                          # 이 이름은 아무거나 지정해도 돼요.
    image: neosmemo/memos:stable  # 사용할 이미지 이름
    container_name: memos         # 컨테이너 이름 (--name 옵션)
    volumes:                      # 볼륨 마운트 옵션 (-v 옵션)
      - ~/.memos/:/var/opt/memos
    ports:                        # 포트 포워딩 옵션 (-p)
      - 5230:5230

비슷한 점들이 보이시나요? 도커 컴포즈는 기본적으로 docker run 으로 할 수 있는 것들을 옮겨온 형태이기 때문에 작성하는 방법도 비슷해요.

여러개의 옵션을 지정할 수 있는 경우는 자식에 - 기호를 써서 전달할 수 있어요. 예를 들면 다음의 명령이 있다고 가정해 볼게요.

docker run -d \
  -v ~/.memos/:/var/opt/memos
  -v ~/.logs/:/var/opt/logs
  -p 80:80
  -p 443:443

이는 컴포즈 파일에서는 이렇게 표현할 수 있어요.

volumes:
  - ~/.memos/:/var/opt/memos
  - ~/.logs/:/var/opt/logs
ports:
  - 80:80
  - 443:443

docker run과 마찬가지로 컴포즈 문법에 대해서도 지금 모두 알 필요는 없어요. 자주 사용하는 name, ports, volumes 정도만 이해하고 필요한 시점에 하나씩 알아가시면 충분할 거예요.


배포하기

이제 생성한 컴포즈 파일을 사용해서 컨테이너를 배포해 볼 차례에요.

다음의 명령어를 실행해 보세요.

docker compose up -d

잘 동작한다면 위와 같이 출력될 거예요.

docker compose up은 현재 경로의 docker-compose.yml 파일을 찾고, 파일에 정의된 대로 컨테이너를 배포해주는 명령어에요. -d 옵션을 함께 사용하면 백그라운드에서 실행되게 돼요. 배포는 정말 간단하죠?

이번에는 docker ps 명령어로 실행중인 컨테이너 상태를 확인해 보세요.

docker run 으로 Memos를 배포했던 것처럼 잘 실행되는 모습을 볼 수 있을 거예요.


관찰하기

이번엔 컴포즈로 배포한 컨테이너를 관찰해 볼게요. 다음의 명령어를 실행해 보세요.

docker compose ps

docker compose ps은 현재 경로의 docker-compose.yml 파일을 찾고 파일에 정의된 컨테이너의 상태를 보여주는 명령어에요. docker ps와 달리 모든 컨테이너를 보여주진 않아요.


삭제하기

마지막으로는 컨테이너를 삭제해 볼 차례에요. 다음의 명령어를 실행해 보세요.

docker compose down

docker compose down은 현재 경로의 docker-compose.yml 파일을 찾고 파일에 정의된 컨테이너들을 중단하고 삭제해주는 명령어에요.


실행해야 하는 내용을 이미 파일로 다 작성해 두었기 때문에, 도커 컴포즈 명령어는 굉장히 간결한 형태에요. 이 정도의 문법만 알아두시더라도 컴포즈를 충분히 사용하실 수 있을 거예요.

여러분이 사용하고 싶은 서버 소프트웨어가 있다면 홈페이지를 한번 방문해 보세요. 설치 가이드 문서가 있다면 아마도 docker run 또는 docker compose 로 배포하는 방법과 실행 예제도 제공하고 있을 거예요. 이를 복사해서 조금씩 수정해서 사용하면 돼요.

원하는 소프트웨어를 구동해 보면서 사용하는 옵션들을 하나씩 알아가 보세요. 그러다 보면 어느덧 도커의 마스터가 되어 있으실 거예요. 진행하다 모르는 옵션은 도커의 문서를 읽어보시거나 요즘은 많이 활용하는 AI 챗봇에게 물어봐도 잘 알려줄 거예요.