# 사이트 배포 가이드

## 개요

이 문서는 Next.js Frontend + FastAPI Backend 사이트를 Ubuntu 서버에 배포하는 전체 과정을 설명합니다.

---

## 배포 순서도

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                         사이트 배포 전체 흐름                                │
└─────────────────────────────────────────────────────────────────────────────┘

1. 사전 준비
   │
   ├─→ DNS 설정 (도메인 → 공인 IP)
   │     ├─ example.com → 59.14.158.123
   │     ├─ www.example.com → 59.14.158.123
   │     └─ api.example.com → 59.14.158.123  ★ 중요: API 서브도메인 필수
   │
   ├─→ 공유기 포트포워딩
   │     ├─ 80 → 192.168.0.201:80 (NPM)
   │     └─ 443 → 192.168.0.201:443 (NPM)
   │
   └─→ 서버 준비
         ├─ Docker 설치
         ├─ Node.js 설치
         └─ Python 설치

2. 소스코드 전송
   │
   ├─→ 압축 (node_modules 제외)
   │     └─ 7z a -tzip project.zip frontend backend -xr!node_modules
   │
   ├─→ 전송 (내부망 경유 권장)
   │     └─ scp project.zip damon@192.168.0.203:~/sites/project/
   │
   └─→ 압축 해제
         └─ unzip project.zip

3. Backend 배포
   │
   ├─→ 가상환경 생성
   │     └─ python3 -m venv venv && source venv/bin/activate
   │
   ├─→ 의존성 설치
   │     └─ pip install -r requirements.txt
   │
   ├─→ ★★★ CORS 설정 수정 ★★★
   │     └─ config.py의 CORS_ORIGINS에 도메인 추가
   │         - http://example.com
   │         - https://example.com
   │         - http://www.example.com
   │         - https://www.example.com
   │
   ├─→ Admin 계정 생성/리셋
   │     └─ python init_admin.py 또는 reset_pw.py 실행
   │
   └─→ 서버 실행
         └─ nohup uvicorn app.main:app --host 0.0.0.0 --port 8001 > ~/logs/backend.log 2>&1 &

4. Frontend 배포
   │
   ├─→ 의존성 설치
   │     └─ npm install
   │
   ├─→ ★★★ 환경변수 설정 ★★★
   │     └─ echo "NEXT_PUBLIC_API_URL=http://api.example.com/api" > .env.local
   │
   ├─→ 빌드
   │     └─ npm run build
   │
   └─→ 서버 실행
         └─ nohup sh -c 'PORT=3001 npm start' > ~/logs/frontend.log 2>&1 &

5. NPM (Nginx Proxy Manager) 설정
   │
   ├─→ Frontend Proxy Host
   │     ├─ Domain: example.com, www.example.com
   │     ├─ Forward: 192.168.0.203:3001
   │     └─ SSL: Let's Encrypt
   │
   └─→ ★★★ API Proxy Host ★★★
         ├─ Domain: api.example.com
         ├─ Forward: 192.168.0.203:8001
         └─ SSL: Let's Encrypt

6. 테스트
   │
   ├─→ 사이트 접속: http://example.com
   ├─→ API 접속: http://api.example.com/api/health
   └─→ Admin 로그인: http://example.com/admin/login
```

---

## 핵심 체크리스트

### 배포 전 필수 확인 사항

- [ ] DNS에 api 서브도메인 A 레코드 추가했는가?
- [ ] NPM에 api.도메인 프록시 설정했는가?
- [ ] Backend CORS_ORIGINS에 도메인 추가했는가?
- [ ] Frontend .env.local에 API URL 설정했는가?
- [ ] Admin 계정이 DB에 존재하는가?

---

## 자주 발생하는 문제와 해결법

### 1. 사이트 로딩만 계속됨 (뱅글뱅글)

**원인**: Frontend가 API에 연결하지 못함

**확인 순서**:
```bash
# 1. Backend 실행 확인
ps aux | grep uvicorn

# 2. API 직접 테스트
curl http://api.example.com/api/health

# 3. .env.local 확인
cat ~/sites/project/frontend/.env.local

# 4. 빌드에 환경변수 적용 확인
grep -r "api.example" ~/sites/project/frontend/.next/ | head -3
```

**해결**:
```bash
# .env.local 설정 후 재빌드
echo "NEXT_PUBLIC_API_URL=http://api.example.com/api" > .env.local
rm -rf .next
npm run build
```

---

### 2. CORS 에러

**원인**: Backend에서 Frontend 도메인을 허용하지 않음

**증상**: 브라우저 Network 탭에서 "CORS error" 표시

**확인**:
```bash
cat ~/sites/project/backend/app/core/config.py | grep CORS
```

**해결**: config.py의 CORS_ORIGINS에 도메인 추가
```python
CORS_ORIGINS: list = [
    "http://localhost:3000",
    "http://example.com",
    "https://example.com",
    "http://www.example.com",
    "https://www.example.com"
]
```

Backend 재시작:
```bash
pkill -f uvicorn
nohup uvicorn app.main:app --host 0.0.0.0 --port 8001 > ~/logs/backend.log 2>&1 &
```

---

### 3. 로그인 안 됨

**원인**: DB에 admin 계정이 없거나 비밀번호가 다름

**확인**:
```bash
# API 직접 테스트
curl -X POST "http://api.example.com/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"비밀번호"}'
```

**해결**: 비밀번호 리셋 스크립트 실행
```bash
cd ~/sites/project/backend
source venv/bin/activate
cat > reset_pw.py << 'EOF'
from app.core.database import SessionLocal
from app.models.admin import Admin
from app.core.security import get_password_hash
db = SessionLocal()
admin = db.query(Admin).filter(Admin.username == 'admin').first()
if admin:
    admin.password_hash = get_password_hash('새비밀번호')
    db.commit()
    print('Password reset')
else:
    print('Admin not found')
db.close()
EOF
python reset_pw.py
```

---

### 4. 포트 충돌 (EADDRINUSE)

**원인**: 기존 프로세스가 포트를 점유 중

**확인**:
```bash
sudo netstat -tlnp | grep 3001
sudo netstat -tlnp | grep 8001
```

**해결**:
```bash
# PID 확인 후 종료
sudo kill -9 <PID>

# 또는 프로세스 이름으로 종료
pkill -f "npm start"
pkill -f uvicorn
```

---

### 5. 500 Internal Server Error (정적 파일)

**원인**: 빌드 파일 손상 또는 캐시 문제

**해결**:
```bash
cd ~/sites/project/frontend
pkill -f "npm start"
rm -rf .next
rm -rf node_modules/.cache
npm run build
nohup sh -c 'PORT=3001 npm start' > ~/logs/frontend.log 2>&1 &
```

---

## 유용한 명령어 모음

### 프로세스 관리

```bash
# 프로세스 확인
ps aux | grep -E "npm|uvicorn|node"

# 포트 사용 확인
sudo netstat -tlnp | grep -E "3001|8001"

# 로그 확인
tail -f ~/logs/frontend.log
tail -f ~/logs/backend.log
```

### 서비스 재시작

```bash
# Frontend 재시작
pkill -f "npm start"
cd ~/sites/project/frontend
nohup sh -c 'PORT=3001 npm start' > ~/logs/frontend.log 2>&1 &

# Backend 재시작
pkill -f uvicorn
cd ~/sites/project/backend
source venv/bin/activate
nohup uvicorn app.main:app --host 0.0.0.0 --port 8001 > ~/logs/backend.log 2>&1 &
```

### API 테스트

```bash
# Health check
curl http://api.example.com/api/health

# 로그인 테스트
curl -X POST "http://api.example.com/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"password"}'
```

---

## 서버 정보

### 네트워크 구성

| 서버 | 내부 IP | 역할 |
|------|---------|------|
| Server1 | 192.168.0.201 | NPM, PostgreSQL, Redis, 모니터링 |
| Server2 | 192.168.0.202 | MongolCar (autonetsellcar.com) |
| Server3 | 192.168.0.203 | Grantech, Cylinx |
| Server4 | 192.168.0.204 | Windows PC (파일 전송 중계) |

### 외부 접속

| 포트 | 용도 |
|------|------|
| 80, 443 | NPM (웹 서비스) |
| 81 | NPM 관리 페이지 |
| 201, 202, 203 | SSH (각 서버) |

### 도메인

| 도메인 | 서비스 |
|--------|--------|
| autonetsellcar.com | MongolCar |
| grantech.kr | Grantech |
| api.grantech.kr | Grantech API |
| cylinx.kr | Cylinx (예정) |

---

## 버전 정보

- Node.js: 20.x
- Python: 3.10
- Next.js: 16.x
- FastAPI: Latest
- Ubuntu: 22.04

---

*최종 업데이트: 2025-12-05*
