Hearth 셋업 로그

정세현·2026년 7월 22일

NHN AX Internship Notes

목록 보기
10/16

1. Hearth가 뭔지

로컬 개발 환경을 위한 서비스 컨트롤 플레인. 여러 개의 로컬 프로젝트(각자 다른 포트에서 실행됨)를 http://localhost 하나의 진입점 아래 경로 기반으로 묶어주는 역할.

구성 요소내용
백엔드FastAPI + uvicorn, 127.0.0.1:8080
├ UI/
├ REST API/api
└ MCP 엔드포인트/mcp
서비스 레지스트리SQLite (routes 테이블)
라우팅nginx (runtime/nginx/conf.d/routes.conf) — 등록 시 자동 생성 + nginx -t 검증 후 reload

중요: hearth는 앱 프로세스를 직접 실행(spawn)하지 않는다. frontend_port / backend_port로 서비스를 등록하면 그 포트에 nginx location만 연결해줄 뿐, npm run dev / uvicorn 같은 실제 프로세스는 사용자가 직접 띄워야 함.

  • launchd(launchd/com.hearth.plist)로 hearth 백엔드 자체를 로그인 시 상시 기동 가능 (KeepAlive=true, 크래시 시 자동 재시작).
  • 선택적 확장: colima(--kubernetes)로 k3s 클러스터를 띄우고 공유 PostgreSQL(pgvector) + Gateway API(NGINX Gateway Fabric)를 배포하면, 앱을 로컬 프로세스가 아니라 k8s Deployment로 올리는 경로도 지원.

2. 오늘 터미널에서 친 명령 (시간순)

2-1. 기본 셋업 — 도구 설치 + sudoers + 백엔드 기동

brew install nginx node python@3.14
./scripts/setup-sudoers.sh
./scripts/start.sh

start.sh가 venv 자동 생성 + 프론트 빌드(frontend/package-lock.json 변경 원인) + uvicorn :8080 기동까지 처리.

2-2. nginx install / start

curl -X POST localhost:8080/api/nginx/install
curl -X POST localhost:8080/api/nginx/start

2-3. launchd 상시 기동 등록

cp launchd/com.hearth.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.hearth.plist

등록 전 plist 파일에 오타 발견 → 세션 중 같이 수정:

  • StandardOutPath / StandardErrorPath>, < 문자가 잘못 섞여 있었음
  • 경로 대소문자(Projectsprojects)가 실제 리포 경로와 불일치
  • 수정 후 plutil -lint launchd/com.hearth.plist → OK 확인
launchctl list | grep hearth
tail -f runtime/backend.out.log

결과: com.hearth의 PID가 -, 종료코드 3, 로그에 [start] uvicorn ... 배너가 반복 → 크래시 루프.

2-4. 크래시 루프 디버깅

tail -n 60 runtime/backend.err.log
# → ERROR: [Errno 48] address already in use (127.0.0.1:8080)

lsof -nP -iTCP:8080 -sTCP:LISTEN
# → PID 52480 (launchd 등록 전에 수동으로 띄워둔 ./scripts/start.sh 프로세스)

ps -p 52480 -o pid,ppid,lstart,command
kill 52480

launchctl list com.hearth
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080
# → 200, PID가 안정적인 새 프로세스로 정착 (예: 70049)

원인: 수동 기동 프로세스가 8080을 물고 있어서 launchd가 올린 인스턴스가 bind 실패 → KeepAlive가 재시작 → 무한 반복.

2-5. colima 기동

brew install colima docker kubectl helm
colima status 2>/dev/null || echo "미기동"
colima start --kubernetes --cpu 6 --memory 12 --disk 100
kubectl config use-context colima
kubectl get nodes

2-6. colima 상태 검증

colima status
colima list
kubectl config current-context
kubectl get nodes -o wide
kubectl get pods -A

결과: 노드 1대 Ready (v1.35.0+k3s1), kube-system의 coredns / local-path-provisioner / metrics-server 3개 파드 Running. postgres·Gateway는 아직 미배포(bare cluster).


3. 앞으로 쳐야 할 명령 — k8s/README.md "재현" 절

provision_db, k8s_httproute_manifest 적용(apply)이 작동하려면 아래를 순서대로 실행.

1) 공유 PostgreSQL (이미 있으면 생략)

kubectl create namespace data
PW=$(openssl rand -hex 24)
kubectl create secret generic postgres-superuser -n data \
  --from-literal=POSTGRES_USER=postgres --from-literal=POSTGRES_PASSWORD="$PW"
kubectl apply -f k8s/postgres/postgres.yaml

2) Gateway API + NGINX Gateway Fabric

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml

helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric --version 2.6.3 \
  -n nginx-gateway --create-namespace --wait

kubectl patch nginxproxy ngf-proxy-config -n nginx-gateway --type merge \
  -p '{"spec":{"kubernetes":{"service":{"type":"NodePort"}}}}'

kubectl apply -f k8s/gateway/gateway.yaml
kubectl apply -f k8s/gateway/httproutes.yaml

3) 호스트 nginx route를 Gateway NodePort로 연결

hearth의 update_route 또는 /api/routes 사용. NodePort 확인:

kubectl get svc -n default -l gateway.networking.k8s.io/gateway-name=hearth-gw \
  -o jsonpath='{.items[0].spec.ports[0].nodePort}'

완료 후 확인

curl -s localhost:8080/api/k8s/status   # GatewayClass/Gateway/postgres/워크로드 상태

실제 서비스를 k8s에 올릴 때 (예시)

# 이미지 빌드 (레지스트리/push 불필요, imagePullPolicy: Never로 로컬 태그 그대로 사용)
docker build -t myapp:local .

# Deployment/Service 매니페스트 작성 후 적용 (직접 작성하거나 k8s_apply 사용)
kubectl apply -f myapp-deployment.yaml

# HTTPRoute 생성 — MCP/REST의 k8s_httproute_manifest(...) 호출 후
kubectl apply -f <생성된 httproute.yaml>

전용 DB가 필요하면 MCP/REST의 provision_db(svc) 호출.


4. 상태 확인용 커맨드 모음

launchctl list | grep hearth              # hearth 백엔드 launchd 상태
tail -f runtime/backend.out.log           # 백엔드 stdout
tail -f runtime/backend.err.log           # 백엔드 stderr
colima status                             # colima/k3s 상태
kubectl get nodes                         # 클러스터 노드
kubectl get pods -A                       # 전체 파드
lsof -nP -iTCP:8080 -sTCP:LISTEN          # 8080 포트 점유 프로세스 확인
profile
I'm the best

0개의 댓글