# 사이트 배포 가이드 ## 개요 이 문서는 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 # 또는 프로세스 이름으로 종료 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*