개발 워크플로우
Lumie는 FE-로컬, BE-클러스터 개발 모델을 사용합니다. 상태형 서비스는 dev 클러스터에서 실행되고, Next.js 프론트엔드만 로컬 머신에서 npm run dev로 동작합니다. 전체 라이프사이클은 Tilt가 조율합니다.
레포별 개발 방식 요약
| 레포 | 개발 방식 | 핫 리로드 |
|---|---|---|
lumie-backend | K8s 배포 (lumie-dev NS), Tekton으로 이미지 빌드 | 재배포 필요 |
lumie-frontend | Tilt local_resource → npm run dev | Next.js HMR (localhost:3000) |
lumie-worker | Tilt K8s 배포 (lumie-dev NS), uvicorn --reload | Python 파일 변경 시 자동 재시작 |
전체 개발 환경 시작
# 워크스페이스 루트에서
.github/tilt-up.sh
.github/tilt-up.sh는 SSH 터널을 열고 Tilt를 실행합니다. 직접 tilt up은 클러스터 API 연결 실패로 동작하지 않습니다. 자세한 내용은 개발 환경을 참조하십시오.
프론트엔드 개발 (local_resource)
프론트엔드는 클러스터에 배포되지 않습니다. Tilt의 local_resource로 로컬 머신에서 npm run dev가 실행됩니다.
동작 원리
# lumie-frontend/Tiltfile 요약
local_resource(
'lumie-frontend',
serve_cmd='npm run dev',
serve_dir='.',
serve_env={
'NEXT_PUBLIC_API_BASE': 'https://dev.lumie-infra.com',
'CUSTOM_DOMAIN_RESOLUTION_ENABLED': 'true',
'CUSTOM_DOMAIN_RESOLVE_TIMEOUT_MS': '2000',
},
labels=['frontend'],
links=['http://localhost:3000'],
)
.env.local파일 불필요 —serve_env가process.env로 주입되어.env파일보다 우선합니다.- 브라우저에서
/api/v1/...요청 →app/api/[...path]/route.ts프록시 →dev.lumie-infra.com/api/v1/... Set-Cookie의Domain+Secure헤더를 제거하여 localhost에서 인증이 정상 동작합니다.
접근 URL
http://localhost:3000
❌ 절대 next dev를 클러스터에 배포하지 마십시오. Turbopack 16.2+ HMR이 Traefik HTTP/2 ALPN과 충돌하여 클라이언트 hydration이 deadlock됩니다.
백엔드 개발
백엔드는 dev 클러스터의 lumie-dev 네임스페이스에 배포됩니다. 로컬에서 코드 변경 후 Tekton 파이프라인 또는 수동 Gradle 빌드로 이미지를 업데이트합니다.
빌드 명령
# JAR 빌드 (테스트 제외)
./gradlew :app:bootJar -x test
# 전체 빌드
./gradlew build
# 특정 모듈 컴파일 확인
./gradlew :modules:auth:compileJava
./gradlew :modules:exam:compileJava
변경 반영 사이클
헬스 프로브
# K8s 배포된 백엔드 상태 확인
kubectl port-forward -n lumie-dev svc/lumie-backend 18080:8080
curl http://localhost:18080/actuator/health
Worker 서비스 개발 (Tilt)
worker 서비스(grading, report, analysis, chatbot)는 lumie-worker/Tiltfile로 K8s 배포됩니다. Python 파일 변경 시 uvicorn --reload로 자동 재시작됩니다.
live_update 동작
# Tiltfile 요약 (grading 예시)
docker_build(
'zot.lumie-infra.com/dev/grading-svc',
context='services/grading',
dockerfile='services/grading/Dockerfile',
entrypoint=['uvicorn', 'main:app', '--host', '0.0.0.0', '--port', '8000', '--reload'],
live_update=[
sync('services/grading', '/app'),
run('pip install -r requirements.txt', trigger=['services/grading/requirements.txt']),
],
)
Worker 서비스 목록
| 서비스 | 역할 | 스케일링 |
|---|---|---|
grading-svc | OMR 채점 (OpenCV) | KEDA RabbitMQ 큐 기반 (min 6, max 15) |
report-svc | 성적표 PDF (Playwright) | 고정 |
analysis-svc | LLM 학습 코멘터리 | 고정 |
chatbot-svc | AI 챗봇 (LangGraph + Gemini 2.5 Flash) | 고정 |
헬스 프로브
# grading-svc port-forward 후 확인
kubectl port-forward -n lumie-worker svc/grading-svc 18000:8000
curl http://localhost:18000/health
전체 개발 환경 구성도
자주 쓰는 명령
백엔드
# JAR 빌드 (테스트 제외)
./gradlew :app:bootJar -x test
# 전체 빌드
./gradlew build
# 전체 테스트
./gradlew test
# 특정 모듈 테스트
./gradlew :modules:auth:test
Tilt
# 전체 환경 시작 (SSH 터널 포함)
.github/tilt-up.sh
# 서비스 강제 재트리거
tilt trigger grading-svc
# 서비스 로그 확인
tilt logs grading-svc
# 현재 상태 확 인
tilt get uiresource
# 전체 종료 (파드 삭제)
tilt down
# 이미지·파드 삭제 없이 Tilt만 종료
tilt down --delete-namespaces=false
주의 사항
- Namespace와 Secret은 ArgoCD가 관리합니다. Tilt로 Secret을 생성하거나 삭제하지 마십시오.
- ArgoCD selfHeal이 활성화되어 있습니다.
kubectl apply로 직접 변경한 리소스는 ArgoCD가 즉시 원복합니다. 변경은 반드시lumie-infra레포 커밋 → ArgoCD sync 경로로 하십시오. - Flyway 마이그레이션이 자동 적용됩니다. 이미 적용된 마이그레이션 파일을 수정하면 체크섬 불일치로 부팅이 실패합니다.
- FE 포트 3000 점유 시:
lsof -ti tcp:3000 | xargs kill로 해제하십시오.