DOCS/troubleshooting/250811_happybell80_ChromaDB메모리손실.md
happybell80 3896d8ae41 docs: ChromaDB 메모리 손실 및 헬스체크 통일 트러블슈팅
- ChromaDB 볼륨 마운트 실패 원인 분석
- Gitea Actions 디렉토리명 불일치 문제
- 헬스체크 엔드포인트 표준화 과정
- Frontend 빌드 환경변수 문제
- CLAUDE.md 규칙 추가 내용 포함
2025-08-11 22:31:24 +09:00

4.2 KiB

ChromaDB 메모리 손실 및 헬스체크 통일

오후 10:30

문제 1: ChromaDB 컨테이너 재시작 시 메모리 손실

증상:

  • 컨테이너 재시작 후 모든 대화 기록 손실
  • ChromaDB에 컬렉션이 하나도 없음
  • SQLite 파일은 존재하지만 데이터 없음

원인 분석:

# docker-compose.yml
volumes:
  - ./chroma_db:/code/chroma_db  # 표준 경로

# .gitea/workflows/deploy.yml (수정 전)
mkdir -p chroma_db_micro logs  # 다른 디렉토리명!

근본 원인:

  • 8월 4일: ONNX 경량화 작업 시 chroma_db_micro 의도적 사용
  • 8월 5일: 표준화 작업으로 chroma_db로 변경
  • Gitea Actions 미동기화: 배포 스크립트는 여전히 chroma_db_micro 생성
  • 결과: 볼륨 마운트 실패 → 컨테이너 내부 임시 저장 → 재시작 시 손실

해결:

# .gitea/workflows/deploy.yml 수정
mkdir -p chroma_db logs  # 디렉토리명 통일

문제 2: 헬스체크 엔드포인트 불일치

증상:

  • Frontend: "연결문제 로빙과 연결할 수 없습니다" 메시지
  • 여러 서비스가 다른 헬스체크 경로 사용
  • Docker healthcheck 실패

원인:

  1. rb10508_micro: /healthz 제공
  2. Gateway: /health 제공
  3. Frontend: /api/health 호출
  4. Docker: /api/health 체크

해결 과정:

# 1. rb10508_micro - 루트 레벨 /healthz 추가
@app.get("/healthz")
async def healthz():
    return {"status": "ok"}

# 2. Gateway - /health → /healthz 변경
@app.get("/healthz")
async def healthz():
    return {"status": "ok"}

# 3. Frontend - 호출 경로 수정
const response = await fetch(`${ROBING_API_URL}/healthz`)

# 4. Docker & Gitea Actions - 헬스체크 경로 통일
test: ["CMD", "curl", "-f", "http://localhost:10508/healthz"]

문제 3: Frontend 빌드 시 환경변수 미적용

증상:

  • .env에 VITE_ROBING_API_URL=https://ro-being.com/gateway 설정
  • 하지만 빌드된 JS는 기본값 /rb10508 사용
  • 422 에러: message vs text 필드 불일치

원인:

# .gitea/workflows/deploy.yml (수정 전)
export VITE_API_URL=http://localhost:8001
# VITE_ROBING_API_URL 누락!
npm run build

해결:

export VITE_API_URL=http://localhost:8001
export VITE_ROBING_API_URL=https://ro-being.com/gateway
npm run build

문제 4: Gateway username 처리

증상:

  • invalid UUID 'happybell80': UUID 형식 오류
  • Frontend가 username 전송, Gateway는 UUID 기대

해결:

# database.py - users 테이블 JOIN으로 username 지원
async def get_robing_info(username: str):
    query = text("""
        SELECT ... 
        FROM workspace_members wm
        JOIN users u ON wm.user_id = u.id
        WHERE u.username = :username
    """)

교훈

1. Gitea Actions 동기화 필수

  • 코드 수정 시 반드시 .gitea/workflows/*.yml 확인
  • 특히 경로, 디렉토리명, 헬스체크 변경 시
  • Docker Compose와 Actions의 볼륨 경로 일치 확인

2. 헬스체크 표준화

  • /healthz 사용 (k8s/nginx 표준)
  • 모든 서비스 통일
  • 빠른 응답 우선

3. 환경변수 빌드 체크

  • CI/CD에서 모든 환경변수 설정 확인
  • 빌드된 결과물 검증
  • 기본값 함정 주의

4. 디렉토리 이름 일관성

  • 개발 → 테스트 → 프로덕션 경로 통일
  • 임시 해결책이 영구화되지 않도록 주의
  • 문서화 필수

5. 보안 고려사항

  • 사용자 인증 검증 부재 발견
  • X-User-Id 헤더 조작 가능
  • JWT 토큰 검증 구현 필요

현재 상태

해결됨

  • ChromaDB 디렉토리 통일 (chroma_db)
  • 헬스체크 /healthz 표준화
  • Frontend 환경변수 설정
  • Gateway username 지원

진행 필요 ⚠️

  • ChromaDB 저장 로직 검증
  • JWT 토큰 인증 구현
  • 기존 데이터 복구 (chroma_db_microchroma_db)

CLAUDE.md 규칙 추가됨

- **Gitea Actions 동기화 필수**:
  - 코드 수정 시 반드시 `.gitea/workflows/*.yml` 파일도 확인
  - 특히 경로, 디렉토리명, 헬스체크 엔드포인트 변경 시 Actions 파일 동기화
  - Docker Compose와 Actions의 볼륨 마운트 경로 일치 확인

이 규칙으로 향후 동일한 문제 예방 가능.