389 lines
7.8 KiB
Markdown
389 lines
7.8 KiB
Markdown
# 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)
|
|
|