2-4. Docker Compose로 멀티 컨테이너 애플리케이션 배포

1. 멀티 컨테이너 애플리케이션 배포의 필요성

단일 컨테이너로 모든 기능을 처리하는 애플리케이션은 단순하고 배포하기 쉽지만, 복잡한 시스템을 구축하는 데는 한계가 있습니다. 예를 들어, 웹 서버와 데이터베이스를 하나의 컨테이너에서 실행하면, 두 기능 간의 격리가 어려워지고, 자원 관리도 비효율적입니다. 또한, 특정 서비스에 문제가 발생했을 때 전체 시스템이 영향을 받을 수 있습니다.

멀티 컨테이너 애플리케이션은 이러한 단점을 보완합니다. 각 컨테이너는 특정 기능을 담당하며, 서로 독립적으로 운영됩니다. 이를 통해 다음과 같은 장점을 얻을 수 있습니다.

  • 분리된 환경: 각 서비스는 자체 컨테이너에서 실행되므로, 서로 간섭 없이 독립적으로 작동합니다.
  • 유연한 확장성: 각 컨테이너를 개별적으로 확장할 수 있습니다. 예를 들어, 트래픽이 증가하면 웹 서버 컨테이너의 수를 늘릴 수 있습니다.
  • 향상된 관리: 각 서비스를 독립적으로 관리하고 업데이트할 수 있습니다.
  • 재사용성: 컨테이너 이미지를 다른 애플리케이션에서 재사용할 수 있습니다.

Docker Compose는 이러한 멀티 컨테이너 애플리케이션을 정의하고 실행하기 위한 도구입니다.

2. Docker Compose의 역할

Docker Compose는 docker-compose.yml 파일을 사용하여 애플리케이션의 서비스, 네트워크, 볼륨 등을 정의합니다. 이 파일을 통해 다음과 같은 작업을 수행할 수 있습니다.

  • 서비스 정의: 애플리케이션을 구성하는 각 컨테이너를 정의합니다. 이미지, 포트 매핑, 환경 변수, 볼륨 등을 설정할 수 있습니다.
  • 네트워크 설정: 컨테이너 간의 통신을 위한 네트워크를 정의합니다. 컨테이너들은 이 네트워크를 통해 서로 통신할 수 있습니다.
  • 볼륨 설정: 컨테이너에서 데이터를 영구적으로 저장하기 위한 볼륨을 정의합니다. 데이터베이스와 같이 지속적인 데이터 저장이 필요한 경우에 사용합니다.
  • 애플리케이션 실행: docker-compose up 명령어를 사용하여 정의된 모든 컨테이너를 한 번에 실행합니다.
  • 애플리케이션 중지/제거: docker-compose down 명령어를 사용하여 실행 중인 모든 컨테이너를 중지하고 제거합니다.

Docker Compose는 Docker를 사용하는 개발 환경에서 멀티 컨테이너 애플리케이션을 쉽게 구축하고 관리할 수 있도록 해줍니다.

3. docker-compose.yml 파일 작성

docker-compose.yml 파일은 YAML 형식으로 작성되며, 애플리케이션의 각 서비스와 설정을 정의합니다. 기본적인 구조는 다음과 같습니다.

version: "3.9" # Docker Compose 파일 형식 버전

services:
  web:
    # 웹 서버 설정
  db:
    # 데이터베이스 설정
  # ... 기타 서비스
  • version: Docker Compose 파일 형식의 버전을 지정합니다.
  • services: 애플리케이션을 구성하는 서비스를 정의합니다. 각 서비스는 컨테이너의 설정 정보를 포함합니다.

3) 웹 서버 서비스 정의

웹 서버 서비스는 애플리케이션의 프론트엔드를 담당합니다. docker-compose.yml 파일에서 다음과 같이 정의할 수 있습니다.

services:
  web:
    image: nginx:latest  # 사용할 이미지
    ports:
      - "80:80"        # 포트 매핑 (호스트:컨테이너)
    volumes:
      - ./html:/usr/share/nginx/html  # 볼륨 마운트
    depends_on:
      - db             # 의존성 설정
  • image: 사용할 Docker 이미지 이름을 지정합니다.
  • ports: 호스트 머신의 포트와 컨테이너 내부 포트를 연결합니다. 80:80은 호스트의 80번 포트를 컨테이너의 80번 포트에 매핑합니다.
  • volumes: 호스트 머신의 디렉터리를 컨테이너 내부의 디렉터리에 마운트합니다. ./html:/usr/share/nginx/html은 현재 디렉터리의 html 폴더를 컨테이너의 /usr/share/nginx/html 폴더에 마운트합니다. 이를 통해 호스트에서 HTML 파일을 수정하면 컨테이너 내부의 파일도 변경됩니다.
  • depends_on: 이 서비스가 의존하는 다른 서비스를 지정합니다. depends_on: - dbweb 서비스가 db 서비스가 실행된 후에 시작되도록 설정합니다.

4) 데이터베이스 서비스 정의

데이터베이스 서비스는 애플리케이션의 데이터를 저장합니다. docker-compose.yml 파일에서 다음과 같이 정의할 수 있습니다.

services:
  db:
    image: postgres:latest  # 사용할 이미지
    environment:
      POSTGRES_USER: myuser # 환경 변수 설정
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"        # 포트 매핑
    volumes:
      - db_data:/var/lib/postgresql/data # 볼륨 마운트
  • image: 사용할 Docker 이미지 이름을 지정합니다.
  • environment: 컨테이너 내부에서 사용할 환경 변수를 설정합니다. POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB는 PostgreSQL 데이터베이스의 사용자, 비밀번호, 데이터베이스 이름을 설정합니다.
  • ports: 호스트 머신의 포트와 컨테이너 내부 포트를 연결합니다. 5432:5432는 호스트의 5432번 포트를 컨테이너의 5432번 포트에 매핑합니다.
  • volumes: 볼륨을 설정합니다. db_data:/var/lib/postgresql/datadb_data라는 이름의 볼륨을 컨테이너의 /var/lib/postgresql/data 디렉터리에 마운트합니다. 이 볼륨은 데이터베이스의 데이터를 영구적으로 저장하는 데 사용됩니다.

5) 네트워크 설정

Docker Compose는 기본적으로 각 서비스에 대한 네트워크를 자동으로 생성합니다. 별도로 네트워크를 정의할 수도 있습니다. 예를 들어, 컨테이너 간의 통신을 위해 별도의 네트워크를 생성하려면 다음과 같이 networks 섹션을 추가할 수 있습니다.

version: "3.9"

services:
  web:
    # ...
    networks:
      - mynetwork

  db:
    # ...
    networks:
      - mynetwork

networks:
  mynetwork:
    driver: bridge
  • networks: 사용할 네트워크를 지정합니다.
  • mynetwork: 네트워크의 이름입니다.
  • driver: 네트워크 드라이버를 지정합니다. bridge는 기본 브리지 네트워크를 사용합니다.

6) 볼륨 설정

볼륨은 컨테이너에서 생성된 데이터를 호스트 머신에 저장하거나 공유하기 위해 사용됩니다. 볼륨은 volumes 섹션에서 정의할 수 있습니다. 예를 들어, 데이터베이스의 데이터를 저장하기 위한 볼륨을 정의하는 방법은 다음과 같습니다.

version: "3.9"

services:
  db:
    # ...
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:
  • volumes: 사용할 볼륨을 지정합니다.
  • db_data: 볼륨의 이름입니다.

4. 실습: 간단한 멀티 컨테이너 애플리케이션 배포

이제 Docker Compose를 사용하여 간단한 멀티 컨테이너 애플리케이션을 배포하는 실습을 진행해 보겠습니다. 이 애플리케이션은 Nginx 웹 서버와 PostgreSQL 데이터베이스로 구성됩니다.

1) 프로젝트 디렉터리 생성 및 파일 준비

프로젝트 디렉터리를 생성하고, 필요한 파일을 준비합니다.

mkdir docker-compose-example
cd docker-compose-example
  • docker-compose-example 디렉터리를 생성하고 이동합니다.

docker-compose.yml 파일을 생성하고 다음 내용을 입력합니다.

version: "3.9"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - db
  db:
    image: postgres:latest
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
volumes:
  db_data:
  • Nginx 웹 서버와 PostgreSQL 데이터베이스를 정의합니다.
  • 웹 서버는 호스트의 80번 포트를 사용하고, 데이터베이스는 호스트의 5432번 포트를 사용합니다.
  • 데이터베이스의 데이터를 저장하기 위해 db_data 볼륨을 사용합니다.

html 디렉터리를 생성하고, index.html 파일을 생성합니다.

mkdir html
cd html
echo "<h1>Hello, Docker Compose!</h1>" > index.html
cd ..
  • html 디렉터리를 생성하고, 간단한 HTML 파일을 생성합니다.

2) 애플리케이션 실행

docker-compose up 명령어를 사용하여 애플리케이션을 실행합니다.

docker-compose up -d
  • -d 옵션은 백그라운드에서 컨테이너를 실행합니다.

Docker Compose는 docker-compose.yml 파일을 읽고, 정의된 서비스들을 실행합니다.

3) 애플리케이션 확인

웹 브라우저에서 http://localhost를 열어 웹 서버가 정상적으로 실행되는지 확인합니다. "Hello, Docker Compose!" 메시지가 표시되면 성공적으로 배포된 것입니다.

4) 데이터베이스 확인

PostgreSQL 클라이언트를 사용하여 데이터베이스에 연결하여 데이터베이스가 정상적으로 실행되는지 확인합니다.

docker exec -it <db_container_id> psql -U myuser -d mydb
  • <db_container_id>docker ps 명령어를 사용하여 데이터베이스 컨테이너의 ID를 확인합니다.

5) 애플리케이션 중지 및 제거

docker-compose down 명령어를 사용하여 애플리케이션을 중지하고 제거합니다.

docker-compose down

5. Docker Compose 사용 시 고려 사항

1) 환경 변수 관리

애플리케이션 설정, API 키, 데이터베이스 자격 증명과 같은 민감한 정보는 환경 변수를 사용하여 관리하는 것이 좋습니다. 환경 변수는 docker-compose.yml 파일에서 직접 설정하거나, .env 파일을 사용하여 관리할 수 있습니다.

version: "3.9"
services:
  web:
    image: nginx:latest
    environment:
      API_KEY: ${API_KEY} # .env 파일에서 정의된 변수
    # ...

.env 파일:

API_KEY=your_api_key

2) 볼륨 관리

볼륨은 컨테이너의 데이터를 영구적으로 저장하는 데 사용됩니다. 볼륨을 적절하게 관리하여 데이터 손실을 방지해야 합니다.

  • 바인드 마운트: 호스트 머신의 디렉터리를 컨테이너에 마운트합니다. 개발 환경에서 코드 변경 사항을 즉시 반영하는 데 유용합니다.
  • 볼륨: Docker가 관리하는 볼륨을 사용합니다. 데이터 백업 및 복원에 용이합니다.

3) 네트워크 구성

컨테이너 간의 통신을 위해 네트워크를 적절하게 구성해야 합니다. Docker Compose는 기본적으로 각 서비스에 대한 네트워크를 자동으로 생성하지만, 필요에 따라 사용자 정의 네트워크를 사용할 수 있습니다.

4) 의존성 관리

depends_on 설정을 사용하여 컨테이너 간의 의존성을 정의합니다. 컨테이너가 시작되는 순서를 제어하고, 서비스가 필요한 다른 서비스가 실행된 후에 시작되도록 보장합니다.

5) Docker Compose 파일 버전

docker-compose.yml 파일의 버전은 Docker Compose의 기능을 결정합니다. 최신 버전의 Docker Compose를 사용하면 최신 기능과 개선 사항을 활용할 수 있습니다.

6. 고급 기능

Docker Compose는 기본적인 기능 외에도 다양한 고급 기능을 제공합니다.

1) 빌드 컨텍스트

build 속성을 사용하여 Docker Compose 파일에서 이미지를 빌드할 수 있습니다. build 속성은 Dockerfile이 있는 디렉터리를 지정합니다.

version: "3.9"
services:
  web:
    build: ./web_app  # Dockerfile 디렉터리
    ports:
      - "80:80"

2) 서비스 스케일링

docker-compose up --scale <service>=<number> 명령어를 사용하여 서비스의 인스턴스 수를 늘리거나 줄일 수 있습니다.

docker-compose up --scale web=3
  • web 서비스의 인스턴스 수를 3개로 늘립니다.

3) 헬스 체크

healthcheck 설정을 사용하여 컨테이너의 상태를 확인합니다. 컨테이너가 정상적으로 작동하지 않으면 Docker Compose가 해당 컨테이너를 다시 시작할 수 있습니다.

version: "3.9"
services:
  web:
    # ...
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
      interval: 1m30s
      timeout: 10s
      retries: 3

4) YAML 파일 확장

Docker Compose 파일은 여러 파일로 분할하여 관리할 수 있습니다. 이를 통해 복잡한 구성을 모듈화하고 재사용성을 높일 수 있습니다. docker-compose.override.yml 파일을 사용하여 기본 설정을 덮어쓸 수도 있습니다.

7. 결론

Docker Compose는 멀티 컨테이너 애플리케이션을 쉽게 정의하고 배포할 수 있도록 도와주는 강력한 도구입니다. docker-compose.yml 파일을 사용하여 애플리케이션의 서비스, 네트워크, 볼륨 등을 정의하고, docker-compose up 명령어를 사용하여 모든 컨테이너를 한 번에 실행할 수 있습니다. 환경 변수 관리, 볼륨 관리, 네트워크 구성, 의존성 관리 등의 고려 사항을 통해 더욱 효율적인 배포 및 관리가 가능합니다.

Docker Compose의 역할 섹션 뒤

Docker Compose는 컨테이너 기반 개발 환경에서 중요한 역할을 하며, 숙련된 개발자라면 반드시 익혀야 할 기술입니다.

비슷한 글 추천

Comments (0)

No comments yet. Be the first to comment!