diff --git a/docs/troubleshooting/250721_happybell80_로빙기억력문제및nginx포트추가.md b/docs/troubleshooting/250721_happybell80_로빙기억력문제및nginx포트추가.md index 232d03a..4e6ab2a 100644 --- a/docs/troubleshooting/250721_happybell80_로빙기억력문제및nginx포트추가.md +++ b/docs/troubleshooting/250721_happybell80_로빙기억력문제및nginx포트추가.md @@ -246,10 +246,57 @@ logger.debug(f"Bot filter check - user: {event_user}, bot_user_id: {slack_servic --- +## 새벽 02시 10분 + +### nginx 499 상태 코드 발견 - Slack 3초 타임아웃 근본 원인 + +**🚨 중요한 발견**: +``` +44.197.111.14 - - [22/Jul/2025:02:12:33 +0900] "POST /rb10508/api/slack/events HTTP/1.1" 499 0 +``` +- **499 = 클라이언트가 연결을 끊음** + +**종합 분석**: + +1. **일부 요청이 서버에 도달하지 않음** + - "로빙 뭐하니?" (Event ID: Ev096TRNGZ2Q) - 원본 없이 retry만 존재 + - nginx까지는 도달했지만 FastAPI 로그에 없음 + +2. **nginx 499 오류 패턴** + - Slack이 응답을 기다리다 3초 후 포기하고 연결 끊음 + - 우리 앱은 요청을 처리하지만 Slack은 이미 떠남 + - 결과: Slack은 응답 못 받았다고 판단하여 retry + +3. **타이밍 문제** + - FastAPI가 200 OK를 반환하는데 시간이 걸림 + - 앱 초기화, 라우팅, 로깅 등으로 지연 발생 + - Slack은 3초 내 응답을 못받으면 연결 끊고 retry + +**해결책 (내일 진행)**: +1. **즉시 200 OK 반환하는 미들웨어 추가** + - 요청 받자마자 200 OK 먼저 반환 + - 실제 처리는 그 다음 + +2. **더 간단한 엔드포인트 구조** + - 불필요한 로깅, 체크 최소화 + - 가장 빠른 경로로 200 OK 반환 + +3. **비동기 처리 아키텍처 재검토** + - FastAPI BackgroundTasks 대신 Celery/RQ 검토 + - 완전한 비동기 분리 + +**현재까지 적용된 해결책**: +- ✅ event_id 기반 중복 체크 +- ✅ 3초 ACK 패턴 (코드상 구현됨) +- ❌ 하지만 실제로는 여전히 499 발생 (FastAPI 자체 지연) + +--- + **교훈**: 1. "큰 그림"보다 "작동하는 코드"가 우선 2. 복잡한 아키텍처보다 심플한 해결책이 때로는 최선 3. 프로토타입 단계에서는 과도한 설계 지양 4. 아키텍처 원칙을 지키는 것이 결국 더 빠른 개발 5. 이벤트 처리에서는 공식 event_id 사용이 텍스트 기반보다 정확 -6. 디버깅 로그는 문제 발생 시점에 미리 추가해야 효과적 \ No newline at end of file +6. 디버깅 로그는 문제 발생 시점에 미리 추가해야 효과적 +7. **nginx 로그 확인이 앱 로그만큼 중요 - 499는 클라이언트 포기 신호** \ No newline at end of file diff --git a/docs/troubleshooting/250722_happybell80_skill-email_Actions설정실패.md b/docs/troubleshooting/250722_happybell80_skill-email_Actions설정실패.md new file mode 100644 index 0000000..4d6fbab --- /dev/null +++ b/docs/troubleshooting/250722_happybell80_skill-email_Actions설정실패.md @@ -0,0 +1,142 @@ +# skill-email Gitea Actions 설정 실패 및 해결 + +**날짜**: 2025-07-22 +**작업자**: happybell80 & Claude + +## 오후 4시 30분 + +### skill-email 자동 배포를 위한 Gitea Actions 설정 + +**요청**: skill-email 저장소에 자동 배포 설정 필요 + +**첫 시도 - 잘못된 접근**: +```yaml +# ❌ 잘못된 방법 - GitHub Actions 스타일 +- name: Deploy to server + uses: appleboy/ssh-action@v0.1.5 # SSH 액션 사용 + with: + host: ro-being.com + username: admin + key: ${{ secrets.SSH_PRIVATE_KEY }} + script: | + cd /home/admin/projects/ivada/skill_email # 잘못된 경로 + git pull origin main + docker compose up -d --build +``` + +**문제점들**: +1. SSH action 사용 - Gitea self-hosted runner에서는 불필요 +2. 경로 오류 - `/home/admin/projects/ivada/skill_email` 존재 안함 +3. GitHub 문법 사용 - `github.event_name` (Gitea에서 작동 안함) +4. runner 설정 오류 - `runs-on: ubuntu-latest` (우리는 self-hosted 사용) + +## 오후 4시 45분 + +### 실패 원인 분석 + +**오류 메시지**: +``` +Error: can't connect without a private SSH key or password +``` + +**근본 원인**: +- Gitea Actions는 self-hosted runner로 서버에서 직접 실행됨 +- SSH로 접속할 필요가 없음 (이미 서버에 있음) +- 다른 프로젝트(rb10508_test, frontend-base) 참고 필요 + +## 오후 5시 00분 + +### 올바른 해결책 - rb10508_test 패턴 적용 + +**수정된 workflow**: +```yaml +name: Deploy Skill-Email Service + +on: + pull_request: + types: [closed] + branches: + - main + +jobs: + deploy: + if: gitea.event.pull_request.merged == true + runs-on: self-hosted # ✅ self-hosted 필수! + + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Stop existing container + run: | + cd /home/admin/skill_email # ✅ 올바른 경로 + docker compose down || true + + - name: Update source code and deploy + run: | + mkdir -p /home/admin/skill_email + cd /home/admin/skill_email + + # 기존 파일 삭제 (설정 파일 제외) + find . -mindepth 1 \ + ! -name '.env' \ + ! -name 'token.json' \ + ! -name 'credentials.json' \ + -exec rm -rf {} + 2>/dev/null || true + + # Actions가 체크아웃한 코드 복사 + cp -r /home/admin/.cache/act/*/hostexecutor/* /home/admin/skill_email/ + + # 배포 + docker compose up -d --build +``` + +**핵심 차이점**: +1. ✅ SSH action 제거 - 직접 명령 실행 +2. ✅ self-hosted runner 사용 +3. ✅ git pull 대신 파일 복사 +4. ✅ 올바른 경로 사용 + +## 오후 5시 15분 + +### 추가 수정사항 + +**문법 오류 수정**: +- `github.event_name` → `gitea.event` (Gitea 전용 문법) +- 불필요한 조건문 제거 (단순화) + +**최종 트리거 설정**: +- PR merge 시에만 실행 (push 제거) +- 중복 실행 방지 + +--- + +## 교훈 + +### 1. **Gitea Actions ≠ GitHub Actions** +- Gitea는 자체 문법 사용 (`gitea.event`) +- SSH action 불필요 (self-hosted runner가 서버에서 직접 실행) + +### 2. **다른 프로젝트 참고 필수** +- rb10508_test, frontend-base의 workflow 먼저 확인 +- 검증된 패턴 재사용 + +### 3. **self-hosted runner 이해** +- `runs-on: self-hosted` 필수 +- runner가 이미 서버에 있으므로 SSH 불필요 +- 직접 명령 실행 가능 + +### 4. **경로 확인** +- 로컬: `/home/happybell/projects/ivada/` +- 서버: `/home/admin/` (projects/ivada 없음) + +### 5. **Actions 코드 위치** +- 체크아웃된 코드: `/home/admin/.cache/act/*/hostexecutor/` +- git pull 대신 이 경로에서 복사 + +--- + +## 결과 +- ✅ 자동 배포 성공 +- ✅ PR merge 시 자동 실행 +- ✅ health check 포함 \ No newline at end of file