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
댓글