Files
hyungi_document_server/docs/deploy.md
hyungi 45cabc9aea refactor: GPU 서버 재구성 + ChromaDB→Qdrant 마이그레이션
- embed_to_chroma.py → embed_to_qdrant.py 리라이트 (bge-m3 + Qdrant REST API)
- auto_classify.scpt: embed_to_qdrant.py 경로 변경 + sourceChannel 덮어쓰기 버그 수정
- requirements.txt: chromadb/schedule 제거, qdrant-client/flask/gunicorn 추가
- credentials.env.example: GPU_SERVER_IP 항목 추가
- GPU 서버 재구성 계획서 (docs/gpu-restructure.md) + dev-roadmap/commands 통합
- CLAUDE.md, README.md, deploy.md 현행화

GPU 서버 변경사항 (이미 적용됨):
  - Ollama: qwen3.5:9b, id-9b 제거 → bge-m3 + bge-reranker-v2-m3
  - Surya OCR 서비스 (:8400, systemd)
  - Docker + NFS + Komga 이전 (:25600)
  - tk-ai-service: Ollama API → OpenAI API 전환 (MLX 35B)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:19:31 +09:00

250 lines
6.6 KiB
Markdown

# Mac mini 배포 가이드
> 마지막 업데이트: 2026-03-29
> 대상: Mac mini M4 Pro (macOS, Python 3.11+)
## 요구사항
- macOS 14+ (Sonoma 이상)
- Python 3.11+ (Homebrew 설치 권장)
- DEVONthink 4 — 실행 중이어야 AppleScript 동작
- OmniFocus 4 — 실행 중이어야 AppleScript 동작
- MLX 서버 — Qwen3.5-35B-A3B, localhost:8800에서 실행 중
- Tailscale — NAS 및 GPU 서버 접근용
## 1. 초기 설치
```bash
# Mac mini에서
cd ~/Documents/code/
git clone https://git.hyungi.net/hyungi/devonthink_home.git "DEVONThink_my server"
cd "DEVONThink_my server"
# Python 가상환경
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
## 2. 인증 정보 설정
```bash
mkdir -p ~/.config/pkm
nano ~/.config/pkm/credentials.env
chmod 600 ~/.config/pkm/credentials.env
```
credentials.env.example을 참고하여 실제 값 입력:
```
# 필수
LAW_OC=<법령API키>
MAILPLUS_HOST=mailplus.hyungi.net
MAILPLUS_PORT=993
MAILPLUS_USER=hyungi
MAILPLUS_PASS=<비밀번호>
NAS_DOMAIN=ds1525.hyungi.net
NAS_TAILSCALE_IP=100.101.79.37
NAS_PORT=15001
# 선택 (향후)
CLAUDE_API_KEY=<키>
#CHAT_WEBHOOK_URL=<Synology Chat 웹훅>
#GPU_SERVER_IP=<Tailscale IP>
```
## 3. 한국 법령 API IP 등록
법령 API 호출 전에 Mac mini의 공인 IP를 등록해야 합니다.
```bash
# Mac mini에서 공인 IP 확인
curl -s ifconfig.me
# open.law.go.kr → 로그인 → 마이페이지 → 인증키 관리
# 위에서 확인한 IP를 서버 IP로 등록
# ※ Tailscale IP(100.x.x.x)가 아니라 실제 공인 IP
# 등록 후 테스트
source venv/bin/activate
python scripts/law_monitor.py
# → "법령 API 에러" 없이 정상 동작 확인
```
## 4. launchd 스케줄 등록
```bash
# 심볼릭 링크 생성
ln -sf ~/Documents/code/DEVONThink_my\ server/launchd/net.hyungi.pkm.law-monitor.plist ~/Library/LaunchAgents/
ln -sf ~/Documents/code/DEVONThink_my\ server/launchd/net.hyungi.pkm.mailplus.plist ~/Library/LaunchAgents/
ln -sf ~/Documents/code/DEVONThink_my\ server/launchd/net.hyungi.pkm.daily-digest.plist ~/Library/LaunchAgents/
# 등록
launchctl load ~/Library/LaunchAgents/net.hyungi.pkm.law-monitor.plist
launchctl load ~/Library/LaunchAgents/net.hyungi.pkm.mailplus.plist
launchctl load ~/Library/LaunchAgents/net.hyungi.pkm.daily-digest.plist
# 확인
launchctl list | grep pkm
```
## 5. PKM API 서버 실행
```bash
# 개발 모드 (수동 실행)
cd ~/Documents/code/DEVONThink_my\ server/
source venv/bin/activate
python scripts/pkm_api_server.py
# 프로덕션 모드 (gunicorn, Phase 3 이후)
# gunicorn -w 2 -b 127.0.0.1:9900 scripts.pkm_api_server:app
# 동작 확인
curl http://localhost:9900/health
curl http://localhost:9900/devonthink/inbox-count
```
API 서버는 GUI 세션에서 실행해야 합니다 (AppleScript가 DEVONthink/OmniFocus GUI에 접근).
## 6. DEVONthink Smart Rule 설정
1. DEVONthink → Preferences → Smart Rules
2. 새 Rule: **"AI Auto Classify"**
- Event: On Import
- Database: Inbox
- Condition: Tags is empty
- Action: Execute Script → External → `applescript/auto_classify.scpt`
3. 새 Rule: **"OmniFocus Sync"**
- Event: On Import
- Database: Projects
- Action: Execute Script → External → `applescript/omnifocus_sync.scpt`
## 7. 수동 테스트
```bash
cd ~/Documents/code/DEVONThink_my\ server/
source venv/bin/activate
# 각 스크립트 수동 실행
python3 scripts/law_monitor.py
python3 scripts/mailplus_archive.py
python3 scripts/pkm_daily_digest.py
# AI 분류 테스트
python3 tests/test_classify.py
```
## 8. 업데이트
```bash
cd ~/Documents/code/DEVONThink_my\ server/
git pull
source venv/bin/activate
pip install -r requirements.txt
# launchd 재로드 (plist가 변경된 경우만)
launchctl unload ~/Library/LaunchAgents/net.hyungi.pkm.law-monitor.plist
launchctl load ~/Library/LaunchAgents/net.hyungi.pkm.law-monitor.plist
# (나머지도 동일)
```
## 9. 로그 확인
```bash
# 스크립트 로그
tail -f logs/law_monitor.log
tail -f logs/mailplus.log
tail -f logs/digest.log
# API 서버 로그
tail -f logs/pkm-api.log
tail -f logs/pkm-api.error.log
# launchd 시스템 로그
log show --predicate 'process == "python3"' --last 1h
```
## 10. 일일 운영 점검
```bash
# 1. launchd 작업 상태
launchctl list | grep pkm
# 2. 오늘의 로그 에러 확인
grep -c ERROR logs/law_monitor.log
grep -c ERROR logs/mailplus.log
# 3. 법령 마지막 확인 시간
cat data/law_last_check.json | python3 -m json.tool
# 4. DEVONthink Inbox 미처리 건수 (API 서버 실행 중이면)
curl -s http://localhost:9900/devonthink/inbox-count
# 5. MLX 서버 상태
curl -s http://localhost:8800/v1/models | python3 -m json.tool
```
## 실행 스케줄
| 스크립트 | 시간 | 용도 |
|---------|------|------|
| law_monitor.py | 매일 07:00 | 법령 변경 모니터링 (한국+US/JP/EU) |
| mailplus_archive.py | 매일 07:00, 18:00 | MailPlus 이메일 수집 |
| pkm_daily_digest.py | 매일 20:00 | 일일 다이제스트 생성 |
| pkm_api_server.py | 상시 (수동/launchd) | REST API (포트 9900) |
## 트러블슈팅
### 법령 API "사용자 정보 검증 실패"
```
원인: Mac mini 공인 IP가 open.law.go.kr에 등록되지 않음
해결:
1. curl -s ifconfig.me 로 현재 공인 IP 확인
2. open.law.go.kr → 마이페이지 → 인증키 관리 → IP 등록
3. IP가 변경되면 다시 등록 필요 (고정 IP 아닌 경우)
```
### MailPlus IMAP Connection refused
```
확인 순서:
1. Synology DSM → MailPlus Server → 서비스 상태 확인
2. IMAP 활성화: DSM → MailPlus Server → 메일 전송 → IMAP 탭
3. 포트: 993(SSL) vs 143(STARTTLS)
4. 방화벽: Synology 방화벽에서 993 포트 확인
5. Tailscale 직접:
python3 -c "import imaplib; m=imaplib.IMAP4_SSL('100.101.79.37', 993); print('OK')"
```
### AppleScript 실행 오류
```
확인:
1. DEVONthink, OmniFocus가 GUI로 실행 중인지 확인
2. 접근성 권한: 시스템 설정 → 개인정보 보호 → 접근성 → python/osascript 허용
3. 수동 테스트:
osascript -e 'tell application "DEVONthink 3" to get name of databases'
```
### MLX 서버 응답 없음
```
확인:
1. MLX 서버 프로세스 확인: ps aux | grep mlx
2. 포트 확인: lsof -i :8800
3. 모델 로드 확인: curl http://localhost:8800/v1/models
4. 재시작 필요 시: (MLX 서버 시작 명령어 실행)
```
### Daily Digest에 데이터가 비어있음
```
확인:
1. DEVONthink이 실행 중인지 확인
2. OmniFocus가 실행 중인지 확인
3. 로그 확인: tail -20 logs/digest.log
4. AppleScript 직접 테스트:
osascript -e 'tell application "DEVONthink 3" to get count of databases'
```