# NPM (Nginx Proxy Manager) 설정 가이드 M1T 서버의 Tr_Code 애플리케이션을 외부에서 접근할 수 있도록 NPM을 설정하는 방법입니다. ## 📋 현재 서버 구조 ``` 외부 인터넷 ↓ R3 공유기 1번 포트 ↓ Proxmox 서버 ↓ NPM 컨테이너 (:80, :443) ↓ 프록시 패스 M1T 서버 (192.168.0.180:80) ↓ nginx 리버스 프록시 ↓ Unix Socket Gunicorn (Tr_Code.sock) ↓ Flask App ↓ localhost:8000 Supabase (Docker) ``` ## ✅ M1T 서버 현재 설정 ### 1. Gunicorn (WSGI 서버) - **방식**: Unix Socket - **위치**: `/home/ckh08045/Tr_Code/Tr_Code.sock` - **Workers**: 3개 - **상태**: ✅ 실행 중 ### 2. nginx (리버스 프록시) - **포트**: 80 (HTTP) - **설정**: `/etc/nginx/sites-enabled/tr_code` - **소켓 연결**: `unix:/home/ckh08045/Tr_Code/Tr_Code.sock` - **상태**: ✅ 실행 중 ### 3. 내부 IP - **IP**: `192.168.0.180` - **포트**: `80` ## 🔧 NPM (Proxmox) 설정 방법 ### 1. NPM 웹 인터페이스 접속 일반적으로 NPM은 다음 주소로 접속합니다: ``` http://proxmox-ip:81 ``` 기본 로그인: - Email: `admin@example.com` - Password: `changeme` (첫 로그인 후 변경) ### 2. Proxy Host 추가 **Dashboard** → **Hosts** → **Proxy Hosts** → **Add Proxy Host** #### Details 탭 ``` Domain Names: - trcode.yourdomain.com (또는 원하는 도메인/서브도메인) Scheme: http Forward Hostname / IP: 192.168.0.180 Forward Port: 80 ☐ Cache Assets ☑ Block Common Exploits ☑ Websockets Support (선택사항, 필요시 체크) ``` #### SSL 탭 ``` SSL Certificate: - Request a new SSL Certificate (Let's Encrypt) 또는 - 기존 인증서 선택 ☑ Force SSL (권장) ☑ HTTP/2 Support (권장) ☑ HSTS Enabled (권장) ☑ HSTS Subdomains (선택사항) 이메일 입력: - your-email@example.com ☑ I Agree to the Let's Encrypt Terms of Service ``` #### Advanced 탭 (선택사항) 추가 nginx 설정이 필요한 경우: ```nginx # 클라이언트 업로드 크기 제한 client_max_body_size 10M; # 타임아웃 설정 (필요시) proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 실제 클라이언트 IP 전달 (이미 기본 설정되어 있음) proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; ``` ### 3. 저장 및 확인 **Save** 버튼 클릭 → SSL 인증서 자동 발급 (Let's Encrypt 사용 시) ## 🌐 접속 방법 ### 외부 접속 (인터넷에서) ``` https://trcode.yourdomain.com ``` ### 내부 네트워크 접속 #### 방법 1: M1T 서버 IP 직접 접근 (같은 네트워크) ``` http://192.168.0.180 ``` - ✅ 빠름 (라우터 거치지 않음) - ✅ SSL 없음 (내부망이므로 안전) - ⚠️ M1T와 같은 네트워크에서만 가능 #### 방법 2: NPM을 통한 접근 (모든 내부망) ``` https://trcode.yourdomain.com 또는 http://npm-server-ip ``` - ✅ 도메인 사용 - ✅ SSL 적용 - ⚠️ 약간의 오버헤드 (NPM 경유) #### 방법 3: hosts 파일 수정 (개발용) 내부 네트워크에서 도메인 이름으로 접근하려면: **Windows**: `C:\Windows\System32\drivers\etc\hosts` **Linux/Mac**: `/etc/hosts` ``` 192.168.0.180 trcode.yourdomain.com ``` 그 후: ``` http://trcode.yourdomain.com ``` ## 🔍 테스트 ### 1. 내부 직접 접근 테스트 ```bash # M1T 서버에서 curl http://localhost/health # 같은 네트워크 다른 컴퓨터에서 curl http://192.168.0.180/health # 응답 예시 {"status":"ok"} ``` ### 2. NPM을 통한 접근 테스트 ```bash # 외부/내부 어디서든 curl https://trcode.yourdomain.com/health # 응답 예시 {"status":"ok"} ``` ### 3. Supabase 연결 테스트 ```bash curl http://192.168.0.180/sb/health # 응답 예시 {"sb":"ok","url":"http://localhost:8000"} ``` ## 🛡️ 보안 설정 (권장) ### 1. 방화벽 설정 (M1T 서버) 외부에서 M1T 80 포트 직접 접근을 차단하고, NPM만 허용: ```bash # ufw 방화벽 사용 시 sudo ufw status # NPM IP만 허용 (예: 192.168.0.100) sudo ufw allow from 192.168.0.100 to any port 80 # 또는 같은 서브넷 전체 허용 sudo ufw allow from 192.168.0.0/24 to any port 80 ``` ### 2. nginx 추가 보안 설정 `/etc/nginx/sites-available/tr_code`에 추가: ```nginx # 특정 IP만 허용 (선택사항) # allow 192.168.0.0/24; # deny all; # 보안 헤더 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; ``` ```bash # 적용 sudo systemctl reload nginx ``` ## 📱 모바일/PWA 접속 ### Android/iOS 브라우저 ``` https://trcode.yourdomain.com ``` ### PWA 설치 (홈 화면에 추가) **Android (Chrome)**: 1. 사이트 접속 2. 메뉴 (⋮) → "홈 화면에 추가" 3. 이름 입력 → 추가 **iOS (Safari)**: 1. 사이트 접속 2. 공유 버튼 (□↑) → "홈 화면에 추가" 3. 이름 입력 → 추가 ## 🔧 문제 해결 ### 502 Bad Gateway (NPM에서) ```bash # M1T에서 nginx 확인 sudo systemctl status nginx curl http://localhost/health # 방화벽 확인 sudo ufw status ``` ### 503 Service Unavailable ```bash # M1T에서 Tr_Code 서비스 확인 sudo systemctl status Tr_Code # 재시작 sudo systemctl restart Tr_Code ``` ### SSL 인증서 발급 실패 (NPM) 1. **도메인이 NPM IP를 가리키는지 확인** ```bash nslookup trcode.yourdomain.com ``` 2. **80 포트가 열려있는지 확인** - Let's Encrypt는 80 포트로 인증 3. **NPM 로그 확인** - Dashboard → System → Logs ### 내부 IP 접근 안됨 ```bash # M1T에서 nginx 포트 확인 sudo netstat -tlnp | grep :80 # 방화벽 확인 sudo ufw status # ping 테스트 ping 192.168.0.180 ``` ## 📊 성능 비교 | 접속 방법 | 속도 | SSL | 외부 접근 | 추천 | |----------|------|-----|----------|------| | 내부 직접 (192.168.0.180) | ⚡ 가장 빠름 | ❌ | ❌ | 내부 개발/테스트 | | NPM 경유 (도메인) | 🔥 빠름 | ✅ | ✅ | 운영 환경 | | localhost (M1T에서) | ⚡⚡ 즉시 | ❌ | ❌ | 서버 직접 작업 | ## 🎯 권장 설정 ### 개발/테스트 환경 ``` 내부 네트워크: http://192.168.0.180 M1T 서버: http://localhost ``` ### 운영 환경 ``` 모든 접속: https://trcode.yourdomain.com (NPM 경유) ``` ## 📝 NPM 추가 설정 예시 ### 여러 서브도메인 설정 ``` trcode.yourdomain.com → 192.168.0.180:80 (Tr_Code) supabase.yourdomain.com → 192.168.0.180:8000 (Supabase) api.yourdomain.com → 192.168.0.180:3000 (다른 API) ``` 각각 별도의 Proxy Host로 추가하면 됩니다. ### 로드 밸런싱 (미래 확장) M1T 서버가 여러 대가 될 경우: ``` trcode.yourdomain.com → - 192.168.0.180:80 (M1T-1) - 192.168.0.181:80 (M1T-2) - 192.168.0.182:80 (M1T-3) ``` NPM에서 자동 로드 밸런싱 지원합니다. ## 💡 팁 ### 1. 도메인이 없는 경우 무료 도메인 서비스 사용: - Duck DNS (https://www.duckdns.org) - No-IP (https://www.noip.com) - FreeDNS (https://freedns.afraid.org) 예: `trcode.duckdns.org` ### 2. 동적 IP 문제 가정용 인터넷은 IP가 변경될 수 있으므로: - DDNS (Dynamic DNS) 사용 - Duck DNS, No-IP 등에서 자동 업데이트 클라이언트 제공 ### 3. 포트 포워딩 (R3 공유기) 외부 접근을 위해 R3 공유기 설정: ``` 외부 포트 80 → Proxmox IP:80 외부 포트 443 → Proxmox IP:443 ``` ## 🔗 관련 문서 - [README.md](README.md) - 전체 설치 가이드 - [PWA_README.md](PWA_README.md) - 안드로이드 앱 변환 가이드 --- **작성일**: 2025-10-13 **M1T 서버 IP**: 192.168.0.180 **현재 포트**: 80 (nginx) → Unix Socket (gunicorn)