본문 바로가기
IT/etc

[Docker-compose] yaml 파일 구조 설명

by IT손흥민 2024. 7. 16.

     

    Docker-compose

    • 하나의 설정파일로 여러개의 컨테이너 관리하는 도구
    • docker run 명령어를 여러개 모아놓은 것
    • docker-compose를 사용하지 않는다면 컨테이너를 하나씩 생성 후 각각 테스트 해야하는 번거로움 발생.매번 CLI로 컨테이너 생성하는 것 보다 여러개의 컨테이너를 하나의 묶음으로 관리하는 것이 더 편리함
    • 각 컨테이너의 의존성, 네트워크, 볼륨 등을 함께 정의
    • 시스템 구축에 필요한 설정 YAML 포맷으로 기재

     

    Docker-compose 대상

    • LLM 모델: Llama3
    • VectorDB: Pgvector
    • 검색 엔진: Elasticsearch
    • 로그 수집: Logstash
    • 시각화: Kibana
    • RAG 실행 python 프로그램

     

    Docker-compose 파일구조

    .
    └── docker-elk
        ├── code_python
        │   ├── Dockerfile
        │   ├── elasticsearch_index.py
        │   ├── elasticsearch_rag.py
        │   ├── requirements.txt
        │   ├── start.sh
        │   └── wait-for-it.sh
        ├── docker-compose.yml
        ├── elasticsearch
        │   ├── Dockerfile
        │   └── config
        │       └── elasticsearch.yml
        ├── kibana
        │   ├── Dockerfile
        │   └── config
        │       └── kibana.yml
        ├── logstash
        │   ├── Dockerfile
        │   ├── config
        │   │   └── logstash.yml
        │   ├── pipeline
        │   │   └── logstash.conf
        │   └── postgresql-42.7.3.jar
        └── setup
            ├── Dockerfile
            ├── entrypoint.sh
            ├── lib.sh
            └── roles
                ├── filebeat_writer.json
                ├── heartbeat_writer.json
                ├── logstash_writer.json
                └── metricbeat_writer.json

     

     

    .env 파일 설명

    • 경로 : docker-elk/.env
    ELASTIC_VERSION=8.9.0
    ELASTIC_PASSWORD='changeme'
    LOGSTASH_INTERNAL_PASSWORD='changeme'
    KIBANA_SYSTEM_PASSWORD='changeme'
    
    PGVECTOR_DB='vectordb'
    PGVECTOR_USER='postgres'
    PGVECTOR_PASSWORD='1234'
    • docker-compose up 명령어를 사용한 상태에서 .env파일을 찾아 내부에 있는 값을 환경 변수로 사용

     

    Docker volumes

    • 도커 볼륨이란
      컨테이너 삭제의 경우 자체 파일 시스템이 사라지는 특성때문에 데이터도 함께 사라진다.
      데이터의 영속성을 보장하기 위한 방법으로 '도커 볼륨'을 사용한다.
      도커 내부에 도커 엔진이 관리하는 볼륨을 생성.
    • 데이터 보존

     

    Docker-compose.yml

    services:
      setup: # 컨테이너1
        profiles:
          - setup
        build:
          context: setup/
          args:
            ELASTIC_VERSION: ${ELASTIC_VERSION}
        init: true
        volumes:
          - ./setup/entrypoint.sh:/entrypoint.sh:ro,Z
          - ./setup/lib.sh:/lib.sh:ro,Z
          - ./setup/roles:/roles:ro,Z
    
        environment:
          ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-}
          LOGSTASH_INTERNAL_PASSWORD: ${LOGSTASH_INTERNAL_PASSWORD:-}
          KIBANA_SYSTEM_PASSWORD: ${KIBANA_SYSTEM_PASSWORD:-}
    
    	networks:
          - elk
        depends_on:
          - elasticsearch
    
    
      elasticsearch: # 컨테이너2
        build:
          context: elasticsearch/
          args:
            ELASTIC_VERSION: ${ELASTIC_VERSION}
        volumes:
          - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro,Z
          - elasticsearch:/usr/share/elasticsearch/data:Z
        ports:
          - 9200:9200
          - 9300:9300
        environment:
          node.name: elasticsearch
          ES_JAVA_OPTS: -Xms512m -Xmx512m
          ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-}
          discovery.type: single-node
        networks:
          - elk
        restart: unless-stopped  
    
      logstash: #컨테이너 3
        build:
          context: logstash/
          args:
            ELASTIC_VERSION: ${ELASTIC_VERSION}
        volumes:
          - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro,Z
          - ./logstash/pipeline:/usr/share/logstash/pipeline:ro,Z
        ports:
          - 5044:5044
          - 50000:50000/tcp
          - 50000:50000/udp
          - 9600:9600
        environment:
          LS_JAVA_OPTS: -Xms256m -Xmx256m
          LOGSTASH_INTERNAL_PASSWORD: 
        networks:
          - elk
        depends_on:
          - elasticsearch
        restart: unless-stopped
    
      kibana: # 컨테이너 4
        build:
          context: kibana/
          args:
            ELASTIC_VERSION: ${ELASTIC_VERSION}
        volumes:
          - ./kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml:ro,Z
        ports:
          - 5601:5601
        environment:
          KIBANA_SYSTEM_PASSWORD: ${KIBANA_SYSTEM_PASSWORD:-}
        networks:
          - elk
        depends_on:
          - elasticsearch
        restart: unless-stopped  
    
    ##################### Pgvector ######################
    
      pgvector: # 컨테이너 5
        image: ankane/pgvector
        ports:
         - 5432:5432
        restart: always
        environment:
          - POSTGRES_DB=${PGVECTOR_DB}
          - POSTGRES_USER=${PGVECTOR_USER}
          - POSTGRES_PASSWORD=${PGVECTOR_PASSWORD}
          - POSTGRES_HOST_AUTH_METHOD=trust
        depends_on:
          - elasticsearch
        volumes:
         - db-data:/var/lib/postgresql/data:rw
        networks:
          - elk  
    
    ##################### ollama ######################
    
      ollama: # 컨테이너 6
        image: ollama/ollama:0.1.37
        ports:
          - 11434:11434
        volumes:
          - ollama_data:/root/.ollama
        healthcheck:
          test: ollama list || exit 1
          interval: 10s
          timeout: 30s
          retries: 5
          start_period: 10s
        # deploy:
        #   resources:
        #     reservations:
        #       devices:
        #         - driver: nvidia
        #           count: 1
        #           capabilities: [ gpu ]
        networks:
          - elk  
    
      open-webui: # 컨테이너 7
        image: ghcr.io/open-webui/open-webui:main
        environment:
          - OLLAMA_API_BASE_URL=http://ollama:11434/api
        ports:
          - 80:8080
        volumes:
          - open_webui_data:/app/backend/data
      ollama-models-pull:
        image: curlimages/curl:8.6.0
        command: >-
          http://ollama:11434/api/pull -d '{"name": "llama3"}'
        depends_on:
          ollama:
            condition: service_healthy
        networks:
          - elk
      
    
    ##################### rag app ######################
    
      rag_app: # 컨테이너 8
        build: code_python/
        depends_on:
          - elasticsearch
        volumes:
          - rag_data:/app/data
        networks:
          - elk
    
    
    networks:
      elk:
        driver: bridge  
    
    volumes:
      elasticsearch:
      db-data:
      ollama_data:
      open_webui_data:
      rag_data:

     

    Docker-compose.yml 설명

    • 경로: docker-elk/docker-compose.yml

    setup 컨테이너

    services:
    
    
      setup: #setup 컨테이너
        profiles:
          - setup
        build:
          context: setup/
          args:
            ELASTIC_VERSION: ${ELASTIC_VERSION}
        init: true
        volumes:
          - ./setup/entrypoint.sh:/entrypoint.sh:ro,Z
          - ./setup/lib.sh:/lib.sh:ro,Z
          - ./setup/roles:/roles:ro,Z
    
        environment:
          ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-}
          LOGSTASH_INTERNAL_PASSWORD: ${LOGSTASH_INTERNAL_PASSWORD:-}
          KIBANA_SYSTEM_PASSWORD: ${KIBANA_SYSTEM_PASSWORD:-}
          
        networks:
          - elk
        depends_on:
          - elasticsearch
    • service는 컨테이너를 정의하는 역할

    • setup: 컨테이너 이름
    • profiles : 서비스를 분리 실행할 수 있음.
    • build:
      • context: 도커파일 경로
      • args: 도커파일에서 사용하는 환경변수(.env)를 파라미터(args)로 지정
    • init: 초기화
    • volumes: 스토리지 마운트(볼륨)를 설정
      • 도커 볼륨명: 컨테이너 내부 경로
      • ro: 읽기 전용
      • Z: 공유 모드
    • environment: 환경변수 설정
    • networks: 접속 네트워크 지정
    • depens_on: 다른 서비스에 대한 의존관계 정의. 위의 내용은 elasticsearch 컨테이너 생성 후 setup 컨테이너 생성

     

    image를 직접 빌드

      pgvector:
        image: ankane/pgvector
        ports:
         - 5432:5432
        restart: always
        environment:
          - POSTGRES_DB=${PGVECTOR_DB}
          - POSTGRES_USER=${PGVECTOR_USER}
          - POSTGRES_PASSWORD=${PGVECTOR_PASSWORD}
          - POSTGRES_HOST_AUTH_METHOD=trust
        depends_on:
          - elasticsearch
        volumes:
         - db-data:/var/lib/postgresql/data:rw
        networks:
          - elk
    • port: 컨테이너 포트 설정
    • 나머지 위와 동일

    networks:
      elk:
        driver: bridge  
    
    volumes:
      elasticsearch:
      db-data:
      ollama_data:
      open_webui_data:
      rag_data:
    • driver: 사용할 네트워크 드라이버 설정 (기본값: bridge)
    • bridge: 하나의 호스트 컴퓨터 내에서 여러 컨테이너들이 서로 소통할 수 있도록 해줌
    • 데이터 볼륨 및 네트워크 정의

    • restart: always를 설정하면 컨테이너가 중단되었을 때 자동으로 다시 시작하도록 설정
    • condition: service_healthy를 설정하여 지정한 컨테이너가 건강한 상태일 때만 컨테이너가 시작되도록 설정
     

     

    Docker-compose 명령어

    docker-compose up
    
    • 이미지 빌드 & 컨테이너 실행
    • 명렁어 하나로 yaml에 정의한 서비스 들이 한꺼번에 컨테이너로 실행
    • pull과 up의 차이
      up: 이미지 tag가 존재하는 경우 repository 이미지에 새로운 업데이트 내용이 존재하더라도 이미지를 다운받지 않음
      pull: 무조건 이미지를 다운로드 받고 업데이트 진행

     

    docker-compose down
    
    • 생성된 컨테이너와 네트워크 종료하고 삭제
    • 옵션에 따라 볼륨도 삭제 가능

     

    docker-compose stop
    
    • 컨테이너 종료

     

    docker-compose exec rag_app ./bin/bash
    • 실행중인 컨테이너에 명령어 실행
    • docker-compose exec {정의한 service name} {실행될 명령어}
    • 위의 명령어는 ./bin/bash로 이동

     

    참고

    https://meetup.nhncloud.com/posts/277
    https://stackoverflow.com/questions/43122080/how-to-use-init-parameter-in-docker-run

     

     

    댓글