콘텐츠로 건너뛰기

Docker Compose를 통한 다중 컨테이너 관리

  • 테크

현재 클라우드 환경에서는 컨테이너화 된 애플리케이션이 보편화되면서 소프트웨어 개발 (Development)와 운영(Operation)의 경계가 모호해지고 있습니다. 과거에는 각 기술 분야가 명확히 구분되어 있었지만, 현재에는 이러한 경계가 모호해지면서 분야 간 격차를 줄이기 위한 새로운 기술 문화와 방법론으로 제시되고 있습니다.

이전 비즈스프링 기술 블로그에서 ‘Docker’에 대해 살펴보았습니다. Docker의 기본 개념을 확인하고 싶으시다면, 아래 링크에서 해당 블로그 글을 참고해 주세요.
📑[비즈스프링블로그] 🔽 가상화의 혁신, Docker에 대해 알아보자

Docker Compose 란

Docker Compose는 다중 컨테이너 애플리케이션의 구성, 실행, 배포를 관리하는 도구입니다. docker-compose.yml이라는 하나의 YAML 파일에 서비스, 네트워크, 볼륨 등의 설정과 컨테이너 실행 옵션을 정의하여 컨테이너 간 실행 순서와 의존성을 효율적으로 관리할 수 있습니다.

Docker Compose 사용하기

Docker Compose를 가장 쉽게 사용하는 방법은 Docker Desktop을 설치하는 것입니다. Docker Desktop에는 Docker Compose와 Docker Engine, Docker CLI가 포함되어 있습니다.

[그림1] docker compose 버전

Docker Compose.yml 작성 & 옵션 활용하기

아래의 예시는 컨테이너 환경으로 Nginx와 PHP를 띄어보는 예시입니다. fastCGi(FPM), PHP 및 Nginx를 설정하고 구성하는 단계입니다.

[그림2] Docker Compose .yml 예시

위의 yaml 파일의 구조를 간단히 설명하자면, 해당 파일은 크게 Services 섹션으로 구성되며 이는 컨테이너 실행을 위한 기본 단위입니다. 각 Service는 자체 Dockerfile을 통해 빌드하거나 Docker 이미지를 지정할 수 있으며, 컨테이너 실행에 필요한 다양한 설정을 포함합니다. Service별로 포트 번호(Port), 환경 변수(env), 디스크 볼륨(volume) 등을 설정할 수 있으며, 각각 고유한 서비스 이름을 부여할 수 있습니다. 네트워크 설정을 별도로 하지 않을 경우, 기본 네트워크가 자동으로 생성되어 동일한 Docker Compose 그룹 내에서 연결되며, 이때 Service 이름이 곧 호스트 이름으로 사용됩니다.

  • container_name : 컨테이너 이름
  • ports : 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드, 외부 노출 포트 지정
  • networks : 최상위 레벨의 networks에 정의된 네트워크 이름을 작성
  • volumes : 서비스 내부 디렉토리와 호스트 디렉토리를 연결하여 데이터 지속성 설정
  • environment : 서비스 내부 환경 변수 설정, 환경 변수가 많은 경우 파일 (.env)로 만들어 지정 (env_file: ./envfile.env)
  • command : 서비스 구동 이후 실행할 명령어 작성
  • depends_on : 서비스 간의 종속성을 의미, 먼저 실행해야 하는 서비스를 지정하여 순서 지정

Nginx에서 PHP가 정상적으로 작동되는지 확인하려면, Nginx의 Root 디렉토리에 phpinfo()를 포함한 파일을 생성하여 웹 브라우저에서 호출해 볼 수 있습니다. 이 과정을 통해 PHP 설정 정보가 출력되는 웹페이지가 아래와 같이 보여지면, 연동을 확인할 수 있습니다.

[그림3] Nginx와 PHP-fpm 연동 확인 예시

Docker Network 활용

Docker Network란, Docker 컨테이너 간의 통신을 관리하고 격리하기 위한 기능을 제공합니다. 각각의 컨테이너가 서로 통신하고 데이터를 주고 받아야 하는 경우, Docker Network를 통해 이러한 컨테이너 간 통신을 쉽게 설정하고 관리할 수 있습니다. 즉, Docker Network는 동일한 호스트 내에서 실행 중인 컨테이너들을 연결하는 논리적 네트워크 개념입니다.

기본적으로 Docker Network는 3가지로 구분되며, 여러 개의 컨테이너를 하나의 Docker Network에 연결하여 통신할 수 있습니다.

✅ Bridge 네트워크 : 하나의 호스트 컴퓨터 내에서 여러 컨테이너들이 서로 통신하기 위해 사용
✅ Host 네트워크 : 컨테이너가 호스트 컴퓨터의 네트워크를 직접 사용하도록 설정
✅ Overlay 네트워크 : 여러 호스트에 분산 된 컨테이너들 간 통신을 위해 사용

Docker Volume 활용

Docker의 모든 데이터는 기본적으로 컨테이너 내부에만 존재하며, 컨테이너 종료와 동시에 삭제되는 휘발성을 가집니다. 이러한 단점을 보완하기 위해 컨테이너 내부의 데이터를 외부 폴더와 연결(볼륨 마운트)할 수 있습니다. 외부 폴더와 연결된 데이터는 컨테이너 내부에서 수정되는 즉시 외부 폴더의 데이터도 동기화되며, 컨테이너가 삭제되어도 데이터는 외부 폴더에 안전하게 보존됩니다.

컨테이너 밖에 있는 폴더와 매칭되는 컨테이너 내부에 존재하는 폴더 경로는 도커 볼륨의 마운트 타입마다 다르며, 아래와 같이 총 3가지가 제공됩니다. 여기서 볼륨=폴더=디렉토리으로 이해주시면 좀 더 이 글을 쉽게 읽으실 수 있습니다.

✅ Bind : 호스트 시스템의 선언된 폴더가 컨테이너에 마운트 되며, 폴더 경로를 본인의 환경에 맞게 사용하는 장점이 있으나, 폴더 경로가 분산되어 관리가 어려움
✅ Volume : Docker에서 관리하는 호스트 파일 시스템의 일부 (Linux의 경우 /var/lib/docker/volumes/)에 저장
✅ tmpfs : 호스트 시스템의 메모리에 저장되며, 보안 혹은 비영구 상태 데이터를 작성해야 하는 이유로 데이터를 유지하지 않으려는 경우 가장 잘 사용

[그림4] Docker Mount된 경로
출처 : https://imjeongwoo.tistory.com/116

Docker Compose 명령어 활용

다음은 간단하게 Docker Compose를 사용할 수 있는 명령어를 알아보도록 하겠습니다. 기본적인 Docker Compose 명령어는 docker-compose.yml 파일을 통해 서비스, 네트워크, 볼륨, 컨테이너 이미지 정의하고 단일 명령으로 여러 컨테이너를 일괄적으로 관리가 가능합니다.

[그림5] docker-compose.yml 경로 폴더의 트리구조
[그림6] Docker compose up -d 명령어 실행 예시

✅ docker compose -d up
– 컨테이너들을 백그라운드에서 실행
-d 옵션은 detached 모드를 의미하며, 컨테이너가 백그라운드에서 실행
– 터미널을 차단하지 않고 다른 작업을 가능

[그림7] docker ps -a 명령어 실행 예시

✅ docker ps – a
– 로컬 도커 컨테이너 리스트 확인
-a 옵션 값으로 모든 ( 종료된 컨테이너 포함) 컨테이너를 확인

[그림8] docker compose down 명령어 실행 예시

✅ docker compose down
– 실행 중인 모든 컨테이너를 중지하고 제거
– 네트워크도 함께 제거
– 단, 볼륨은 기본적으로 보존

[그림9] docker compose –dry-run up –build -d 명령어 실행 예시

✅ docker compose build
– Docker Compose 설정 파일(docker-compose.yml)에 정의된 모든 서비스의 이미지를 빌드
– Dockerfile을 기반으로 새로운 이미지를 생성하며, 코드나 설정이 변경되었을 때 이미지를 다시 빌드할 때 사용

✅ docker compose –dry-run up –build -d
--dry-run : 실제로 명령을 실행하지 않고 어떤 작업이 수행될지 표시
-build : 서비스 시작 전에 이미지를 다시 빌드
-d : 백그라운드에서 실행하는 명령어로 컨테이너에서 어떤 작업이 이루어질지 미리 확인 가능

이번 시간에는 기본적인 Docker 뿐 아니라 Multi Container Application을 구현할 수 있는 Docker Compose CLI 의 기본적인 사용법을 알아보았습니다. Docker Compose 를 사용하여 DevOps 환경을 맛보기로 접해보는 의미 있는 시간이었습니다. 더 심화된 Docker의 내용은 다음 시리즈 글로 소개해드리도록 하겠습니다. 감사합니다.

References
  • https://github.com/IshtarStar/docker-compose-nginx-phpfpm
  • https://docs.docker.com/reference/cli/docker/compose/
  • https://velog.io/@choidongkuen/%EC%84%9C%EB%B2%84-Docker-Network-%EC%97%90-%EB%8C%80%ED%95%B4

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다