zioinfo-mail/docker-compose.yml
DESKTOP-TKLFCPR\ython 4b7904d14a feat(setup): DB 선택/pgvector/Qdrant/Gitea 통합
[DB 선택 대화형 프롬프트]
- setup/lib/db_select.sh: 설치 시 SQLite/PostgreSQL/PostgreSQL+pgvector 선택
- DB_TYPE 환경변수로 무인 설치 지원
- pgvector 자동 빌드/설치 (소스 빌드 폴백 포함)
- .env DATABASE_URL 자동 기록

[Vector DB]
- docker-compose.yml: postgres를 pgvector/pgvector:pg15 이미지로 교체
- Qdrant: docker profile=vector 로 선택적 활성화
- docs/vector_db_guide.md: pgvector/Qdrant 사용법 + 시나리오

[Gitea 온프레미스 Git 서버]
- docker-compose.yml: gitea/gitea:1.21-rootless 서비스 추가
- setup/lib/gitea_setup.sh: 공통 설치/초기화 함수
- setup/gitea_init.sh: 독립 실행형 초기화 스크립트
  - 관리자 계정 생성
  - guardia 조직 + GUARDiA 저장소 생성
  - main 브랜치 보호 (PR + 리뷰 1명 필수)
  - develop 브랜치 생성
  - 개발자 계정 (engineer1/2, pm1, admin) + feature/이름/init 브랜치 자동 생성
  - 현재 소스 자동 push

[브랜치 전략]
  main         : 보호 브랜치, PR 필수, 리뷰 1명 필수
  develop      : 통합 브랜치, force-push 금지
  feature/이름/기능: 개인 개발 브랜치

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 19:32:47 +09:00

260 lines
8.9 KiB
YAML

# ============================================================
# GUARDiA ITSM — Full Stack docker-compose (개발/테스트용)
# ============================================================
# 사용법:
# docker compose up -d # 전체 스택 시작
# docker compose up -d guardia # GUARDiA만 시작 (DB/Redis는 외부)
# docker compose logs -f guardia
# docker compose down -v # 볼륨 포함 완전 삭제
#
# 환경변수:
# .env 파일에 GUARDIA_LICENSE_KEY, SECRET_KEY 등을 설정하세요.
# (itsm/.env가 없으면 기본값 사용)
# ============================================================
x-common-env: &common-env
PYTHONIOENCODING: utf-8
PYTHONUNBUFFERED: "1"
DATABASE_URL: postgresql+asyncpg://guardia:guardia@postgres:5432/guardia
REDIS_URL: redis://redis:6379/0
OLLAMA_BASE_URL: http://ollama:11434
MESSENGER_BASE_URL: http://messenger:8002
MESSENGER_OPS_ROOM: ops
services:
# ── GUARDiA ITSM ────────────────────────────────────────
guardia:
build:
context: .
dockerfile: Dockerfile
image: guardia-itsm:latest
container_name: guardia-itsm
ports:
- "8001:8001"
environment:
<<: *common-env
SECRET_KEY: ${SECRET_KEY:-change_this_in_production_min_32chars}
ALGORITHM: HS256
ACCESS_TOKEN_EXPIRE_MINUTES: 480
GUARDIA_LLM_MODEL: ${GUARDIA_LLM_MODEL:-llama3.1:8b}
GUARDIA_LICENSE_KEY: ${GUARDIA_LICENSE_KEY:-}
# OAuth 소셜 로그인 (선택)
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET:-}
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID:-}
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET:-}
KEYCLOAK_BASE_URL: ${KEYCLOAK_BASE_URL:-}
KEYCLOAK_REALM: ${KEYCLOAK_REALM:-master}
KEYCLOAK_CLIENT_ID: ${KEYCLOAK_CLIENT_ID:-guardia}
KEYCLOAK_CLIENT_SECRET: ${KEYCLOAK_CLIENT_SECRET:-}
CATALINA_HOME: /app/tomcat
volumes:
- guardia-uploads:/app/uploads
- guardia-db:/app # SQLite 개발 모드용 (PostgreSQL 사용 시 불필요)
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- guardia-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8001/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# ── Nginx 리버스 프록시 ──────────────────────────────────
nginx:
image: nginx:alpine
container_name: guardia-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./docker/nginx/guardia.conf:/etc/nginx/conf.d/default.conf:ro
- ./docker/nginx/ssl:/etc/nginx/ssl:ro # HTTPS 인증서 (선택)
depends_on:
- guardia
networks:
- guardia-net
restart: unless-stopped
# ── PostgreSQL ───────────────────────────────────────────
postgres:
# pgvector/pgvector:pg15 = PostgreSQL 15 + pgvector 확장 포함
# vector 타입 사용: SR 유사도 검색, KB 시맨틱 검색
image: pgvector/pgvector:pg15
container_name: guardia-postgres
environment:
POSTGRES_DB: guardia
POSTGRES_USER: guardia
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-guardia}
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- guardia-pgdata:/var/lib/postgresql/data
ports:
- "5432:5432" # 개발용 노출 (운영에서는 제거)
networks:
- guardia-net
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U guardia -d guardia"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# ── Redis ────────────────────────────────────────────────
redis:
image: redis:7-alpine
container_name: guardia-redis
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- guardia-redis:/data
ports:
- "6379:6379" # 개발용 노출
networks:
- guardia-net
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
# ── Ollama (온프레미스 sLLM) ─────────────────────────────
# 모델은 볼륨(guardia-ollama-models)에 저장 — 이미지에 포함 안 함
# GPU 지원: docker-compose.gpu.yml 오버라이드 파일 참조
ollama:
image: ollama/ollama:latest
container_name: guardia-ollama
volumes:
- guardia-ollama-models:/root/.ollama # 모델 영구 저장
ports:
- "11434:11434" # 내부 전용 (외부 노출 금지 권장)
environment:
OLLAMA_HOST: 0.0.0.0
networks:
- guardia-net
restart: unless-stopped
# GPU 사용 시 아래 주석 해제 (docker-compose.gpu.yml에서 override)
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:11434/api/version"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
# ── Tomcat 9 (WAS 환경 시뮬레이션) ──────────────────────
tomcat:
image: tomcat:9.0-jdk17-temurin-jammy
container_name: guardia-tomcat
ports:
- "8080:8080"
volumes:
- guardia-tomcat-webapps:/usr/local/tomcat/webapps
- guardia-tomcat-logs:/usr/local/tomcat/logs
- ./docker/tomcat/tomcat-users.xml:/usr/local/tomcat/conf/tomcat-users.xml:ro
environment:
JAVA_OPTS: "-Xms512m -Xmx1024m -Djava.awt.headless=true"
CATALINA_OPTS: "-server -XX:+UseParallelGC"
networks:
- guardia-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8080/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
# ── Qdrant (전용 벡터 DB — 고성능 시맨틱 검색) ───────────
# pgvector보다 빠른 ANN 검색이 필요할 때 사용
# QDRANT_ENABLED=true 시 guardia에서 QDRANT_URL=http://qdrant:6333 설정
qdrant:
image: qdrant/qdrant:v1.7.4
container_name: guardia-qdrant
profiles: ["vector"] # docker compose --profile vector up 으로 활성화
ports:
- "6333:6333"
- "6334:6334"
volumes:
- guardia-qdrant:/qdrant/storage
environment:
QDRANT__SERVICE__GRPC_PORT: "6334"
networks:
- guardia-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:6333/healthz"]
interval: 30s
timeout: 5s
retries: 3
# ── Gitea (온프레미스 Git 서버) ──────────────────────────
# 형상관리: 저장소 생성, 브랜치 보호, PR 워크플로우
gitea:
image: gitea/gitea:1.21-rootless
container_name: guardia-gitea
ports:
- "3000:3000" # HTTP (web + API)
- "2222:2222" # SSH
environment:
USER_UID: "1000"
USER_GID: "1000"
GITEA__DEFAULT__APP_NAME: "GUARDiA Git"
GITEA__SERVER__HTTP_PORT: "3000"
GITEA__SERVER__SSH_PORT: "2222"
GITEA__SERVER__ROOT_URL: "http://localhost:3000/"
GITEA__DATABASE__DB_TYPE: "sqlite3"
GITEA__DATABASE__PATH: "/var/lib/gitea/data/gitea.db"
GITEA__REPOSITORY__DEFAULT_BRANCH: "main"
GITEA__GIT__DEFAULT_BRANCH: "main"
GITEA__SECURITY__INSTALL_LOCK: "true"
GITEA__SERVICE__DISABLE_REGISTRATION: "false"
volumes:
- guardia-gitea-data:/var/lib/gitea
- guardia-gitea-config:/etc/gitea
- /etc/timezone:/etc/timezone:ro
networks:
- guardia-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:3000/api/v1/version"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
# ── 볼륨 ─────────────────────────────────────────────────
volumes:
guardia-db:
guardia-uploads:
guardia-pgdata:
guardia-redis:
guardia-ollama-models: # Ollama 모델 (로컬 경로 마운트 가능)
guardia-tomcat-webapps:
guardia-tomcat-logs:
guardia-qdrant: # Qdrant 벡터 데이터
guardia-gitea-data: # Gitea 저장소 + DB
guardia-gitea-config: # Gitea 설정
# ── 네트워크 ──────────────────────────────────────────────
networks:
guardia-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16