# ntfy 푸시 알림 서버 — 운영 매뉴얼 ## 개요 ntfy는 Web Push(VAPID)의 iOS 제한, 전송 보장 부재 등을 보완하는 푸시 알림 채널이다. 모바일 ntfy 앱으로 알림을 수신하고, 탭하면 딥링크로 해당 페이지로 이동한다. - **Docker 서비스명**: `ntfy` - **내부 URL**: `http://ntfy:80` (Docker 네트워크) - **외부 URL**: `https://ntfy.technicalkorea.net` (Cloudflare Tunnel) - **호스트 포트**: `30750` - **설정 파일**: `ntfy/etc/server.yml` - **데이터**: `ntfy_cache` Docker 볼륨 (`/var/cache/ntfy`) ## 초기 설정 (최초 1회) ### 1. Cloudflare Tunnel 설정 Zero Trust 대시보드 → Tunnels → Public Hostname 추가: | Subdomain | Domain | Service | |-----------|--------|---------| | ntfy | technicalkorea.net | http://ntfy:80 | ### 2. 컨테이너 기동 ```bash docker compose up -d ntfy ``` ### 3. 관리자 계정 + 토큰 발급 ```bash # 관리자 계정 생성 (비밀번호 입력 프롬프트) docker exec -it tk-ntfy ntfy user add --role=admin admin # API 토큰 발급 docker exec -it tk-ntfy ntfy token add admin # 출력 예: tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2 ``` ### 4. .env에 토큰 설정 ```env NTFY_PUBLISH_TOKEN=<위에서 발급받은 토큰> ``` ## 메시지 발행 (서버 → 사용자) ### curl로 테스트 ```bash # 기본 메시지 curl -H "Authorization: Bearer $NTFY_PUBLISH_TOKEN" \ -d "테스트 메시지입니다." \ http://localhost:30750/tkfactory-test # 제목 + 딥링크 포함 curl -H "Authorization: Bearer $NTFY_PUBLISH_TOKEN" \ -H "Title: 설비수리 요청" \ -H "Tags: wrench" \ -H "Click: https://tkfb.technicalkorea.net/pages/admin/repair-management.html" \ -d "A동 CNC 설비 수리 요청이 접수되었습니다." \ http://localhost:30750/tkfactory-user-1 # 우선순위 높은 알림 (5=max, 3=default, 1=min) curl -H "Authorization: Bearer $NTFY_PUBLISH_TOKEN" \ -H "Title: 긴급 안전 알림" \ -H "Priority: 5" \ -H "Tags: warning" \ -d "즉시 확인이 필요합니다." \ http://localhost:30750/tkfactory-user-1 ``` ### 토픽 네이밍 규칙 | 토픽 | 용도 | |------|------| | `tkfactory-user-{userId}` | 사용자별 개인 알림 (Phase 2에서 사용) | | `tkfactory-test` | 테스트용 | ### 주요 헤더 | 헤더 | 설명 | 예시 | |------|------|------| | `Title` | 알림 제목 | `설비수리 요청` | | `Click` | 탭 시 열릴 URL (딥링크) | `https://tkfb.technicalkorea.net/pages/work/tbm.html` | | `Tags` | 이모지 태그 ([목록](https://docs.ntfy.sh/emojis/)) | `wrench`, `warning`, `white_check_mark` | | `Priority` | 1(min) ~ 5(max) | `5` | | `Authorization` | 인증 토큰 | `Bearer tk_...` | ## 사용자 관리 ```bash # 사용자 목록 docker exec tk-ntfy ntfy user list # 일반 사용자 추가 docker exec -it tk-ntfy ntfy user add username # 사용자 삭제 docker exec tk-ntfy ntfy user del username # 특정 토픽 접근 권한 부여 (read-write / read-only / write-only) docker exec tk-ntfy ntfy access username 'tkfactory-user-*' read-only # 토큰 발급 docker exec tk-ntfy ntfy token add username # 토큰 목록 docker exec tk-ntfy ntfy token list # 토큰 삭제 docker exec tk-ntfy ntfy token remove username tk_... ``` ## 모바일 앱 설정 (수신자용) ### Android 1. Play Store에서 **ntfy** 설치 2. 설정(⚙️) → **Default server** → `https://ntfy.technicalkorea.net` 입력 3. 우측 상단 사용자 아이콘 → 로그인 (발급받은 계정/비밀번호 또는 토큰) 4. **+** → 토픽 `tkfactory-user-{본인userId}` 구독 ### iOS 1. App Store에서 **ntfy** 설치 2. Settings → **Default server** → `https://ntfy.technicalkorea.net` 입력 3. 로그인 후 토픽 구독 (Android와 동일) ## 서버 설정 (server.yml) | 항목 | 현재 값 | 설명 | |------|---------|------| | `auth-default-access` | `deny-all` | 인증 없이 접근 불가 | | `cache-duration` | `72h` | 메시지 보관 기간 (주말 포함 3일) | | `visitor-request-limit-burst` | `60` | 버스트 요청 한도 | | `visitor-request-limit-replenish` | `5s` | 요청 한도 보충 주기 | 설정 변경 후 컨테이너 재시작: ```bash docker compose restart ntfy ``` ## 트러블슈팅 ### 401 Unauthorized - 토큰이 맞는지 확인: `docker exec tk-ntfy ntfy token list` - `auth-default-access: deny-all` 상태에서 토큰 없이 요청하면 발생 ### 모바일 앱에서 알림이 안 옴 - Cloudflare Tunnel Public Hostname에 `ntfy.technicalkorea.net` 등록되었는지 확인 - 앱의 Default server URL이 `https://ntfy.technicalkorea.net`인지 확인 - 앱에서 로그인했는지, 토픽을 구독했는지 확인 - 폰 설정에서 ntfy 앱 알림 권한이 켜져 있는지 확인 ### 컨테이너 로그 확인 ```bash docker logs tk-ntfy --tail 50 docker logs tk-ntfy -f # 실시간 ``` ## Phase 2 예정 사항 (참고) - `system1-factory/api/models/notificationModel.js`의 `sendPushToUsers()`에서 ntfy 발송 연동 - `push_subscriptions` 테이블에 `channel` 컬럼 추가 (`web_push` | `ntfy`) - ntfy 구독 사용자에게는 Web Push 미발송 (중복 방지) - notification-bell.js에서 ntfy 구독 토글 UI 추가