384 lines
7.6 KiB
Markdown
384 lines
7.6 KiB
Markdown
# Synology NAS-only Paper Monitor → Joplin
|
|
|
|
이 구성은 Windows PC가 꺼져 있어도 Synology NAS만으로 다음 작업을 수행합니다.
|
|
|
|
```text
|
|
Paper APIs
|
|
↓
|
|
Python paper-monitor
|
|
↓
|
|
SQLite deduplication
|
|
↓
|
|
Daily Markdown report
|
|
↓
|
|
Joplin Terminal import
|
|
↓
|
|
Joplin WebDAV sync
|
|
↓
|
|
Synology WebDAV sync folder
|
|
↓
|
|
PC / phone / tablet Joplin
|
|
```
|
|
|
|
## 중요한 원칙
|
|
|
|
NAS의 Joplin WebDAV 동기화 폴더에 Markdown 파일을 직접 복사하지 않습니다.
|
|
반드시 Joplin Terminal을 통해 note를 만들고 `joplin sync`를 실행합니다.
|
|
|
|
`joplin-profile/`은 NAS의 Joplin CLI 전용 로컬 profile입니다. PC Joplin profile과 공유하지 마세요.
|
|
|
|
---
|
|
|
|
## 1. NAS에 프로젝트 복사
|
|
|
|
예시:
|
|
|
|
```text
|
|
/volume1/docker/paper-monitor/
|
|
```
|
|
|
|
이 폴더에 이 ZIP의 전체 파일을 복사합니다.
|
|
|
|
최소 파일:
|
|
|
|
```text
|
|
paper-monitor/
|
|
├── Dockerfile.nas
|
|
├── docker-compose.nas.yml
|
|
├── config.nas.yaml
|
|
├── .env
|
|
├── src/
|
|
├── nas/
|
|
├── data/
|
|
└── joplin-profile/
|
|
```
|
|
|
|
`data`와 `joplin-profile` 폴더는 없으면 Docker 실행 시 생성할 수 있지만, 미리 만드는 것을 권장합니다.
|
|
|
|
```bash
|
|
mkdir -p /volume1/docker/paper-monitor/data
|
|
mkdir -p /volume1/docker/paper-monitor/joplin-profile
|
|
```
|
|
|
|
---
|
|
|
|
## 2. .env 생성
|
|
|
|
`.env.nas.example`을 복사하여 `.env`로 만듭니다.
|
|
|
|
```bash
|
|
cp .env.nas.example .env
|
|
```
|
|
|
|
예:
|
|
|
|
```env
|
|
IEEE_API_KEY=
|
|
SEMANTIC_SCHOLAR_API_KEY=
|
|
CROSSREF_MAILTO=your_email@example.com
|
|
|
|
JOPLIN_WEBDAV_URL=https://your-nas-hostname:5006/Joplin
|
|
JOPLIN_WEBDAV_USERNAME=joplin-sync
|
|
JOPLIN_WEBDAV_PASSWORD=YOUR_PASSWORD
|
|
JOPLIN_NOTEBOOK=Radar Papers
|
|
JOPLIN_WRITE_ENABLED=false
|
|
JOPLIN_IGNORE_TLS_ERRORS=false
|
|
```
|
|
|
|
### JOPLIN_WEBDAV_URL
|
|
|
|
현재 PC/스마트폰 Joplin에서 사용 중인 **동일한 Joplin WebDAV sync folder**를 지정해야 합니다.
|
|
|
|
예:
|
|
|
|
```text
|
|
https://your-nas-hostname:5006/Joplin
|
|
```
|
|
|
|
NAS Docker 컨테이너에서 해당 주소에 접근할 수 있어야 합니다.
|
|
|
|
### 보안
|
|
|
|
`.env`에는 WebDAV 비밀번호와 API key가 있으므로 Git에 올리지 마세요.
|
|
|
|
---
|
|
|
|
## 3. 처음에는 쓰기 기능을 끈 상태로 실행
|
|
|
|
처음에는 반드시:
|
|
|
|
```env
|
|
JOPLIN_WRITE_ENABLED=false
|
|
```
|
|
|
|
로 두는 것을 권장합니다.
|
|
|
|
이 상태에서는 **기존 Joplin WebDAV 데이터를 Joplin CLI profile로 동기화만 하고 새 note는 만들지 않습니다.**
|
|
|
|
가능하면 첫 테스트 전에 NAS의 Joplin WebDAV 폴더를 백업하세요.
|
|
|
|
---
|
|
|
|
## 4. Docker image 빌드
|
|
|
|
NAS SSH에서:
|
|
|
|
```bash
|
|
cd /volume1/docker/paper-monitor
|
|
sudo docker compose -f docker-compose.nas.yml build
|
|
```
|
|
|
|
Joplin Terminal npm package와 Python paper-monitor가 한 image에 설치됩니다.
|
|
|
|
---
|
|
|
|
## 5. Joplin WebDAV sync-only 테스트
|
|
|
|
```bash
|
|
sudo docker compose -f docker-compose.nas.yml run --rm paper-monitor-nas /app/nas/test_sync.sh
|
|
```
|
|
|
|
정상적이면 `joplin sync`가 완료되고 Joplin status가 출력됩니다.
|
|
|
|
이때 다음 폴더에 NAS용 Joplin local profile이 저장됩니다.
|
|
|
|
```text
|
|
/volume1/docker/paper-monitor/joplin-profile/
|
|
```
|
|
|
|
이 profile은 이후 실행에서도 유지됩니다.
|
|
|
|
---
|
|
|
|
## 6. 논문 자동 작성 활성화
|
|
|
|
sync-only 테스트가 정상이라면 `.env`를 수정합니다.
|
|
|
|
```env
|
|
JOPLIN_WRITE_ENABLED=true
|
|
```
|
|
|
|
현재 IEEE key가 아직 Waiting이라면 `config.nas.yaml`에서:
|
|
|
|
```yaml
|
|
sources:
|
|
ieee:
|
|
enabled: false
|
|
```
|
|
|
|
Semantic Scholar key도 아직 승인되지 않았다면:
|
|
|
|
```yaml
|
|
semantic_scholar:
|
|
enabled: false
|
|
```
|
|
|
|
Crossref만으로도 전체 동작을 시험할 수 있습니다.
|
|
|
|
---
|
|
|
|
## 7. 1회 전체 테스트
|
|
|
|
```bash
|
|
sudo docker compose -f docker-compose.nas.yml run --rm paper-monitor-nas
|
|
```
|
|
|
|
동작 순서:
|
|
|
|
```text
|
|
1. Joplin CLI → WebDAV sync (remote 변경 먼저 가져오기)
|
|
2. 논문 API 검색
|
|
3. SQLite 중복 제거
|
|
4. 오늘 발견한 논문으로 일일 누적 Markdown 생성
|
|
5. Joplin의 동일 날짜 report가 있으면 교체
|
|
6. Markdown을 Joplin notebook으로 import
|
|
7. Joplin CLI → WebDAV sync
|
|
```
|
|
|
|
정상 로그 예:
|
|
|
|
```text
|
|
Synchronising Joplin from WebDAV before writing...
|
|
Running paper monitor...
|
|
Crossref 'automotive radar' -> 10
|
|
...
|
|
Importing report into Joplin notebook: Radar Papers
|
|
Synchronising Joplin changes to WebDAV...
|
|
Completed: Radar Literature - 2026-08-12 (... papers)
|
|
```
|
|
|
|
Joplin에서 다음 note가 보이면 성공입니다.
|
|
|
|
```text
|
|
Radar Papers
|
|
└── Radar Literature - 2026-08-12
|
|
```
|
|
|
|
---
|
|
|
|
## 8. 같은 날 여러 번 실행해도 괜찮은 이유
|
|
|
|
`papers.db`에 논문별 최초 발견 날짜를 저장합니다.
|
|
|
|
예:
|
|
|
|
```text
|
|
06:00 실행: 논문 A, B 발견
|
|
→ 오늘 report = A, B
|
|
|
|
12:00 재실행: 논문 C 추가 발견
|
|
→ 오늘 report = A, B, C
|
|
```
|
|
|
|
따라서 같은 날짜의 Joplin report를 교체해도 앞서 발견한 논문이 사라지지 않습니다.
|
|
|
|
---
|
|
|
|
## 9. Synology Task Scheduler에서 매일 자동 실행
|
|
|
|
DSM:
|
|
|
|
```text
|
|
Control Panel
|
|
→ Task Scheduler
|
|
→ Create
|
|
→ Scheduled Task
|
|
→ User-defined script
|
|
```
|
|
|
|
예를 들어 매일 오전 06:00으로 설정합니다.
|
|
|
|
User-defined script:
|
|
|
|
```bash
|
|
/volume1/docker/paper-monitor/run_scheduled.sh
|
|
```
|
|
|
|
NAS에 따라 Docker 경로가 다를 수 있습니다.
|
|
|
|
SSH에서 확인:
|
|
|
|
```bash
|
|
which docker
|
|
```
|
|
|
|
출력된 경로로 `/usr/local/bin/docker`를 교체하세요.
|
|
|
|
---
|
|
|
|
## 10. 자동 실행 로그 확인
|
|
|
|
```bash
|
|
ls -1t /volume1/docker/paper-monitor/data/logs/scheduler-*.log | head -n 1
|
|
tail -n 200 "$(ls -1t /volume1/docker/paper-monitor/data/logs/scheduler-*.log | head -n 1)"
|
|
```
|
|
|
|
논문 수집 결과:
|
|
|
|
```text
|
|
/volume1/docker/paper-monitor/data/papers.db
|
|
/volume1/docker/paper-monitor/data/outbox/
|
|
/volume1/docker/paper-monitor/data/last_result.json
|
|
```
|
|
|
|
---
|
|
|
|
## 11. API 활성화
|
|
|
|
### IEEE
|
|
|
|
IEEE developer application이 Active가 된 뒤:
|
|
|
|
`.env`:
|
|
|
|
```env
|
|
IEEE_API_KEY=YOUR_KEY
|
|
```
|
|
|
|
`config.nas.yaml`:
|
|
|
|
```yaml
|
|
ieee:
|
|
enabled: true
|
|
```
|
|
|
|
401/403이 발생하면 해당 실행에서 IEEE query는 한 번 실패한 뒤 중단하도록 수정되어 있습니다.
|
|
|
|
### Semantic Scholar
|
|
|
|
API key 승인 후:
|
|
|
|
```env
|
|
SEMANTIC_SCHOLAR_API_KEY=YOUR_KEY
|
|
```
|
|
|
|
그리고:
|
|
|
|
```yaml
|
|
semantic_scholar:
|
|
enabled: true
|
|
```
|
|
|
|
HTTP 429가 발생하면 exponential backoff로 재시도하고, 계속 제한되면 해당 실행의 Semantic Scholar query를 중단합니다.
|
|
|
|
---
|
|
|
|
## 12. HTTPS 인증서 문제
|
|
|
|
정상적인 공인 인증서를 사용한다면:
|
|
|
|
```env
|
|
JOPLIN_IGNORE_TLS_ERRORS=false
|
|
```
|
|
|
|
를 유지하세요.
|
|
|
|
자체 서명 인증서 때문에 sync가 실패할 때만 임시 진단 목적으로:
|
|
|
|
```env
|
|
JOPLIN_IGNORE_TLS_ERRORS=true
|
|
```
|
|
|
|
를 사용할 수 있습니다. 가능하면 인증서를 정상 구성하는 것이 우선입니다.
|
|
|
|
---
|
|
|
|
## 13. Joplin E2EE를 사용하는 경우
|
|
|
|
기존 Joplin 동기화에 End-to-End Encryption을 활성화해 둔 경우, 새 NAS Joplin CLI client에서도 master key/password 설정이 필요할 수 있습니다.
|
|
|
|
그 경우 자동 쓰기를 켜기 전에 Joplin CLI의 E2EE 상태와 복호화를 먼저 설정해야 합니다.
|
|
|
|
```bash
|
|
sudo docker compose -f docker-compose.nas.yml run --rm paper-monitor-nas \
|
|
joplin --profile /joplin-profile e2ee status
|
|
```
|
|
|
|
E2EE를 사용하지 않는 경우에는 이 단계가 필요 없습니다.
|
|
|
|
---
|
|
|
|
## 14. 운영 시 권장 구성
|
|
|
|
```yaml
|
|
app:
|
|
lookback_days: 14
|
|
min_relevance: 2
|
|
|
|
sources:
|
|
ieee:
|
|
enabled: true # 승인 후
|
|
semantic_scholar:
|
|
enabled: true # 승인 후
|
|
crossref:
|
|
enabled: true
|
|
|
|
ai:
|
|
enabled: false # 처음에는 비용 없는 상태로 운영
|
|
|
|
joplin:
|
|
enabled: false # NAS에서는 Joplin CLI wrapper가 담당
|
|
```
|
|
|
|
Joplin Data API용 `joplin.py`는 Windows Desktop 방식 호환을 위해 프로젝트에 유지하지만 NAS 경로에서는 사용하지 않습니다.
|