Spaces:
Running
Running
| # 영웅문 S# AI 메뉴 검색 — Hugging Face Spaces (Docker SDK) 이미지 | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # 단일 컨테이너 안에서: | |
| # - Streamlit UI (포트 7860) | |
| # - Qdrant 임베디드(local) 모드 → 별도 서버 불필요 | |
| # - Qdrant 쿼리 인덱스(Q↔Q) → 메뉴 색인과 같은 인스턴스 공유 | |
| # 색인은 "이미지 빌드 시점"에 미리 생성한다(아래 RUN). 런타임은 로드만 → | |
| # HF 헬스체크 타임아웃 없이 빠르게 기동. | |
| # | |
| # docker-compose(FastAPI + Qdrant 컨테이너) 배포는 Dockerfile.api 를 사용한다. | |
| FROM python:3.13-slim | |
| WORKDIR /app | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # torch CPU 전용 휠 | |
| RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu | |
| COPY requirements.txt . | |
| RUN pip install --no-cache-dir -r requirements.txt | |
| # 임베디드 Qdrant + 모델 캐시 설정 | |
| ENV HF_HOME=/app/.hf_cache \ | |
| TRANSFORMERS_OFFLINE=0 \ | |
| TOKENIZERS_PARALLELISM=false \ | |
| PYTHONUNBUFFERED=1 \ | |
| QDRANT_MODE=local \ | |
| QDRANT_PATH=/app/data/qdrant_local | |
| # ── 모델 미리 다운로드 (캐시 레이어) ───────────────────────────────────────── | |
| # bge-m3(~2GB)를 코드 COPY 전에 받아 별도 레이어로 굽는다. requirements.txt가 | |
| # 그대로면 코드가 바뀌어도 이 레이어는 캐시 → 매 푸시마다 재다운로드(~수 분) 스킵. | |
| RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('BAAI/bge-m3')" | |
| # ── 빌드 시점 색인 생성 (검색 로직 코드와 분리) ────────────────────────────── | |
| # 색인 내용은 data/ + 빌드 스크립트 + 색인 관련 코어 파일에만 의존한다. | |
| # search_engine.py 등 나머지 코드는 아래 `COPY . .`에서 따로 받으므로, | |
| # 검색 로직만 수정할 땐 이 레이어가 캐시되어 색인 재빌드(메뉴 901개 재임베딩)를 | |
| # 통째로 건너뛴다. (아래 코어 파일/스크립트/데이터가 바뀔 때만 재빌드) | |
| # [주의] 빌드 스크립트가 import하는 코어 파일은 빠짐없이 여기 포함해야 한다. | |
| # qdrant_conn(공유 클라이언트)·query_vectorstore(Q↔Q 인덱스)가 누락되면 | |
| # 02/20 빌드 스크립트가 ImportError로 죽는다. | |
| COPY config.py ./ | |
| COPY core/__init__.py core/embedder.py core/vectorstore.py core/bm25_index.py \ | |
| core/qdrant_conn.py core/query_vectorstore.py core/ | |
| COPY scripts/ scripts/ | |
| COPY data/ data/ | |
| RUN python scripts/06_rebuild_bm25.py \ | |
| && python scripts/02_build_vectordb.py --reset \ | |
| && python scripts/20_build_query_index.py --from-pool --reset | |
| # HF Spaces가 컨테이너를 비-root UID로 띄워도 런타임 쓰기가 가능하도록 | |
| # (Qdrant/Chroma 락파일, 검색 로그) 쓰기 경로 권한 개방. | |
| # COPY . . 이전에 둬서 코드만 바뀔 땐 이 chmod도 캐시된다. | |
| RUN mkdir -p /app/logs \ | |
| && chmod -R 777 /app/data /app/logs /app/.hf_cache | |
| # ── 나머지 애플리케이션 코드 ───────────────────────────────────────────────── | |
| # 코드 한 줄만 바뀌어도 여기만 무효화된다(빠른 COPY). 위 모델/색인 레이어는 | |
| # 캐시 유지 → 검색 코드 수정 후 재빌드가 ~1분 안쪽으로 단축. | |
| COPY . . | |
| EXPOSE 7860 | |
| # APP_MODE 분기: 미설정/streamlit → 데모 UI, mcp → MCP 서버(streamable-http). | |
| # 같은 이미지로 데모 Space와 MCP Space를 둘 다 운영(각 Space의 Secret만 다름). | |
| CMD ["bash", "start.sh"] | |