본문 바로가기
DevOps & Infra/Docker

Docker Compose로 다중 컨테이너 애플리케이션 구축하기

by hyunji00pj 2025. 6. 26.

이번 예제는 Fast API기반 웹 애플리케이션과 여러 서비스를 통합한 구조이다.

 

docker-compose.yml은 FastAPI 서버, 벡터 데이터베이스인 milvus, 관계형 데이터베이스인 Postgres, 객체 스토리지인 MinIO, 메타데이터 저장소인 ectd 관리 UI인 pgAdmin을 포함하고 있다.

 

docker-compose.yml 파일을 통해서 애플리케이션을 효율적으로 배포할 수 있다.

 

docker-compose.yml: 여러 도커 컨테이너 서비스를 정의하고 관리하는 설정 파일

 

 

  • Milvus 서비스: AI/ML용 벡터 데이터베이스로, v2.3.3 버전을 사용해 단일 모드로 실행된다. 포트 19530과 9091을 열어 외부 접근 가능하며, etcdminio에 의존해 데이터와 메타데이터를 관리한다. volumes/milvus로 데이터 지속성 보장한다.
  • etcd 서비스: 분산 키-값 저장소로, Milvus의 메타데이터를 저장한다. v3.5.5 버전 사용, volumes/etcd로 데이터 저장, 자동 컴팩션 및 쿼터 설정으로 안정성 확보.
    • 분산 키-값 저장소: 여러 컴퓨터에 데이터를 나누어 저장하고, 빠르게 접근할 수 있는 데이터베이스 방식입니다. "키-값"은 사물함처럼 "키"(이름)로 "값"(데이터)을 저장하는 구조예요. "분산"은 여러 대의 서버에 데이터를 복제해 안정성과 속도를 높이는 기술입니다.
    • Milvus의 메타데이터 저장: Milvus는 벡터 데이터를 저장하는 데이터베이스로, 여기서 "메타데이터"는 데이터에 대한 추가 정보(예: 데이터 이름, 생성 날짜, 분류)를 뜻합니다. etcd는 Milvus가 이 정보를 효율적으로 관리하도록 돕습니다.
    • v3.5.5 버전 사용: etcd 소프트웨어의 특정 버전을 사용해 안정성과 호환성을 보장합니다.
    • volumes/etcd로 데이터 저장: 로컬 디렉토리(./volumes/etcd)를 컨테이너에 연결해 데이터가 영구적으로 저장되도록 합니다. 컴퓨터를 껐다 켜도 데이터가 사라지지 않게 해줍니다.
    • 자동 컴팩션 및 쿼터 설정으로 안정성 확보:
      • 자동 컴팩션: 오래된 데이터를 정리해 저장 공간을 최적화.
      • 쿼터 설정: 저장 용량(예: 4GB)을 제한해 시스템이 과부하 걸리지 않도록 관리.
      • 이렇게 해서 데이터가 꼬이거나 서버가 느려지는 것을 방지합니다.
  • MinIO 서비스: 객체 스토리지로, Milvus 데이터 저장을 지원한다. RELEASE.2023-03-20T20-16-18Z 버전 사용, 포트 9001에서 콘솔 제공, volumes/minio로 데이터 유지.
    • 객체 스토리지: 파일이나 데이터를 "객체" 단위로 저장하는 방식으로, 큰 파일(예: 이미지, 비디오)이나 비구조화 데이터를 효율적으로 관리합니다. 일반적인 폴더 구조(파일시스템)와 달리, 객체는 고유한 ID로 저장됩니다.
    • Milvus 데이터 저장 지원: Milvus는 벡터 데이터를 저장하지만, 큰 데이터(예: 이미지 원본)나 백업 파일은 MinIO에 저장됩니다. Milvus가 이 데이터를 참조할 수 있도록 연결합니다.
    • RELEASE.2023-03-20T20-16-18Z 버전 사용: MinIO 소프트웨어의 특정 버전을 사용해 안정성과 성능을 보장합니다.
    • 포트 9001에서 콘솔 제공: MinIO는 웹 인터페이스(콘솔)를 통해 데이터를 관리할 수 있으며, 포트 9001에서 접근 가능합니다(예: http://localhost:9001).
    • volumes/minio로 데이터 유지: 로컬 디렉토리(./volumes/minio)를 컨테이너에 연결해 데이터가 영구 저장되도록 합니다. 서버 재시작에도 데이터 유지.
  • Postgres 서비스: 관계형 데이터베이스로, 15-alpine 버전 사용한다, 포트 5432를 열어 외부 연결 가능. platform 데이터베이스를 기본으로 설정하고, volumes/postgres로 데이터 저장.
  • pgAdmin 서비스: Postgres 관리용 웹 UI로, 포트 5050에서 실행한다. 기본 계정(admin@admin.com, admin)으로 로그인 가능하며, postgres 서비스에 의존한다.
  • 네트워크: app-network라는 브리지 네트워크로 모든 서비스를 연결, 서비스 간 통신과 호스트 머신(host.docker.internal) 접근을 지원한다.

아래 예제는 docker-compose.yml이며 주석을 달아서 설명하였다

 

# docker-compose.yml: 여러 도커 컨테이너 서비스를 정의하고 관리하는 설정 파일
# 버전: Docker Compose 파일 형식 버전
version: '3'

# 서비스: 실행할 컨테이너 목록 정의
services:
  # 앱 서비스: 메인 애플리케이션 (FastAPI/uvicorn, run.py 실행)
  app:
    # 빌드 설정: Dockerfile을 사용해 이미지 빌드
    build:
      context: .  # 빌드 컨텍스트: 현재 디렉토리
      dockerfile: Dockerfile  # 사용할 Dockerfile 이름
    # 포트 매핑: 호스트의 7777 포트를 컨테이너의 7777 포트에 연결
    ports:
      - "7777:7777"
    # 볼륨 마운트: 로컬 디렉토리를 컨테이너에 연결해 코드/데이터 실시간 반영
    volumes:
      - ./app:/app/app  # 로컬 app/ 디렉토리를 컨테이너 /app/app에 마운트
      - ./data:/app/data  # 로컬 data/ 디렉토리를 컨테이너 /app/data에 마운트
      - ./poppler:/usr/local/poppler  # 로컬 poppler/ 디렉토리를 컨테이너 /usr/local/poppler에 마운트
      - ./app/static:/app/app/static  # 로컬 app/static/ 디렉토리를 컨테이너 /app/app/static에 마운트
    # 환경 변수 파일: .env 파일에서 환경 변수 로드
    env_file:
      - .env
    # 환경 변수: 애플리케이션 실행에 필요한 설정
    environment:
      - OLLAMA_API_URL=http://host.docker.internal:11434/api/generate  # Ollama AI 모델 API URL
      - OLLAMA_MODEL=gemma3  # 사용할 Ollama 모델 이름
      - APP_WORKERS=4  # Uvicorn 워커 수 (병렬 처리)
    # 리소스 제한: 컨테이너의 CPU와 메모리 사용량 제한
    deploy:
      resources:
        limits:
          cpus: '4'  # 최대 4 CPU 코어 사용
          memory: 8G  # 최대 8GB 메모리 사용
    # 의존성: Milvus 서비스가 먼저 시작되어야 함
    depends_on:
      - milvus
    # 네트워크: app-network에 연결
    networks:
      - app-network
    # 호스트 추가: Docker 내부에서 호스트 머신 접근 가능
    extra_hosts:
      - "host.docker.internal:host-gateway"  # 호스트 머신을 host.docker.internal로 매핑

  # Milvus 서비스: 벡터 데이터베이스 (AI/ML용 벡터 검색)
  milvus:
    image: milvusdb/milvus:v2.3.3  # Milvus 이미지, 버전 2.3.3
    container_name: milvus-standalone  # 컨테이너 이름 지정
    command: ["milvus", "run", "standalone"]  # Milvus 단일 모드 실행 명령
    # 포트 매핑: Milvus의 기본 포트와 gRPC 포트
    ports:
      - "19530:19530"  # Milvus 기본 포트
      - "9091:9091"    # gRPC 포트
    # 볼륨 마운트: Milvus 데이터 저장
    volumes:
      - ./volumes/milvus:/var/lib/milvus  # 로컬 volumes/milvus를 컨테이너 /var/lib/milvus에 마운트
    # 환경 변수: Milvus 설정
    environment:
      - ETCD_ENDPOINTS=etcd:2379  # etcd 서비스 엔드포인트
      - MINIO_ADDRESS=minio:9000  # MinIO 스토리지 엔드포인트
      - MINIO_ACCESS_KEY=minioadmin  # MinIO 액세스 키
      - MINIO_SECRET_KEY=minioadmin  # MinIO 비밀 키
    # 네트워크: app-network에 연결
    networks:
      - app-network
    # 의존성: etcd와 MinIO가 먼저 시작
    depends_on:
      - etcd
      - minio

  # etcd 서비스: 분산 키-값 저장소 (Milvus 메타데이터 저장용)
  etcd:
    image: quay.io/coreos/etcd:v3.5.5  # etcd 이미지, 버전 3.5.5
    # 볼륨 마운트: etcd 데이터 저장
    volumes:
      - ./volumes/etcd:/etcd  # 로컬 volumes/etcd를 컨테이너 /etcd에 마운트
    # 환경 변수: etcd 설정
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision  # 자동 컴팩션 모드
      - ETCD_AUTO_COMPACTION_RETENTION=1000  # 컴팩션 보존 리비전 수
      - ETCD_QUOTA_BACKEND_BYTES=4294967296  # 백엔드 스토리지 쿼터 (4GB)
      - ETCD_SNAPSHOT_COUNT=50000  # 스냅샷 트리거 리비전 수
    # 실행 명령: etcd 서버 시작
    command: etcd --advertise-client-urls=http://etcd:2379 --listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
    # 네트워크: app-network에 연결
    networks:
      - app-network

  # MinIO 서비스: 객체 스토리지 (Milvus 데이터 저장용)
  minio:
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z  # MinIO 이미지, 특정 릴리스
    # 볼륨 마운트: MinIO 데이터 저장
    volumes:
      - ./volumes/minio:/minio_data  # 로컬 volumes/minio를 컨테이너 /minio_data에 마운트
    # 환경 변수: MinIO 인증 설정
    environment:
      - MINIO_ACCESS_KEY=minioadmin  # MinIO 액세스 키
      - MINIO_SECRET_KEY=minioadmin  # MinIO 비밀 키
    # 실행 명령: MinIO 서버 시작, 콘솔 포트 9001
    command: minio server /minio_data --console-address ":9001"
    # 네트워크: app-network에 연결
    networks:
      - app-network

  # Postgres 서비스: 관계형 데이터베이스
  postgres:
    image: postgres:15-alpine  # Postgres 이미지, 버전 15 (Alpine 경량)
    container_name: postgres  # 컨테이너 이름 지정
    # 포트 매핑: Postgres 기본 포트
    ports:
      - "5432:5432"
    # 환경 변수: 데이터베이스 설정
    environment:
      - POSTGRES_USER=postgres  # 데이터베이스 사용자
      - POSTGRES_PASSWORD=postgres  # 데이터베이스 비밀번호
      - POSTGRES_DB=platform  # 기본 데이터베이스 이름
    # 볼륨 마운트: Postgres 데이터 저장
    volumes:
      - ./volumes/postgres:/var/lib/postgresql/data  # 로컬 volumes/postgres를 컨테이너 /var/lib/postgresql/data에 마운트
    # 네트워크: app-network에 연결
    networks:
      - app-network

  # pgAdmin 서비스: Postgres 관리용 웹 인터페이스
  pgadmin:
    image: dpage/pgadmin4  # pgAdmin 이미지
    container_name: pgadmin  # 컨테이너 이름 지정
    # 포트 매핑: pgAdmin 웹 인터페이스 포트
    ports:
      - "5050:80"
    # 환경 변수: pgAdmin 로그인 설정
    environment:
      - PGADMIN_DEFAULT_EMAIL=admin@admin.com  # 기본 관리자 이메일
      - PGADMIN_DEFAULT_PASSWORD=admin  # 기본 관리자 비밀번호
      - PGADMIN_LISTEN_PORT=80  # 웹 인터페이스 포트
    # 의존성: Postgres 서비스가 먼저 시작
    depends_on:
      - postgres
    # 네트워크: app-network에 연결
    networks:
      - app-network

# 네트워크: 서비스 간 통신을 위한 가상 네트워크
networks:
  app-network:
    driver: bridge  # 브리지 네트워크, 서비스 간 통신 가능

 

'DevOps & Infra > Docker' 카테고리의 다른 글

도커 에러 메세지 정리  (0) 2025.06.20