# AutonetSellCar.com 배포 가이드 ## 1. 서버 아키텍처 ### 1.1 서버 구성도 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 개발 환경 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ server5 (집 Win11) │ │ │ Remote Desktop │ │ ▼ │ │ server4 (회사 Win11) ─── Claude Code 실행, 소스 편집 │ │ │ │ │ │ git push staging main │ │ ▼ │ ├─────────────────────────────────────────────────────────────────────────────┤ │ 운영 환경 (192.168.0.x) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ server1 (192.168.0.201) server2 (192.168.0.202) │ │ ┌─────────────────────┐ ┌─────────────────────────────────────┐ │ │ │ PostgreSQL (5432) │◄────────►│ Docker Containers │ │ │ │ Redis (6379) │ │ ├─ autonet-frontend (:3000) │ │ │ │ Nginx Proxy Manager │ │ ├─ autonet-backend (:8000) │ │ │ └─────────────────────┘ │ └─ carmodoo-agent │ │ │ │ │ │ │ │ Git Bare Repository │ │ │ │ └─ /opt/autonet/git/autonet.git │ │ │ │ │ │ │ │ Staging: /opt/autonet/staging/ │ │ │ │ Production: /opt/autonet/production/│ │ │ └─────────────────────────────────────┘ │ │ │ │ server3 (192.168.0.203) - grantech.kr (별도 서비스) │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 1.2 서버별 역할 | 서버 | IP | 역할 | 주요 서비스 | |------|-----|------|------------| | server5 | 집 | 원격 접속용 | Remote Desktop | | server4 | 회사 | **개발서버** | Claude Code, VS Code, Git | | server1 | 192.168.0.201 | **DB/인프라** | PostgreSQL, Redis, Nginx Proxy Manager | | server2 | 192.168.0.202 | **운영서버** | Docker (Frontend, Backend, Agent) | | server3 | 192.168.0.203 | 기타 | grantech.kr | --- ## 2. 소스 코드 버전 관리 ### 2.1 Git 저장소 구조 ``` server4 (개발서버) server2 (운영서버) ┌────────────────────┐ ┌────────────────────────────────┐ │ D:\Workspace\ │ │ /opt/autonet/ │ │ claudeCode\ │ git push │ ├── git/autonet.git (bare) │ │ AutonetSellCar.com │ ───────────► │ ├── staging/ (checkout) │ │ │ staging │ ├── production/ (rsync copy) │ │ .git/ │ │ ├── releases/ (백업) │ │ ├── remote: staging│ │ └── scripts/ (배포스크립트) │ └────────────────────┘ └────────────────────────────────┘ ``` ### 2.2 Git Remote 설정 ```bash # 개발서버(server4)에서 확인 git remote -v # staging ssh://damon@192.168.0.202/opt/autonet/git/autonet.git (fetch) # staging ssh://damon@192.168.0.202/opt/autonet/git/autonet.git (push) ``` --- ## 3. 배포 흐름 (Data Flow) ### 3.1 전체 배포 프로세스 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ Step 1: 개발 (server4) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ 코드 수정 → git add → git commit │ │ │ │ $ git add -A && git commit -m "변경 내용" │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Step 2: 스테이징 배포 (자동) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ $ git push staging main │ │ │ │ [자동 실행: post-receive hook] │ │ 1. /opt/autonet/staging/ 에 코드 checkout │ │ 2. Docker 컨테이너 빌드 및 시작 │ │ 3. 스테이징 서버 가동 (포트 3001, 8001) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Step 3: 스테이징 검증 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Frontend: http://192.168.0.202:3001 │ │ Backend: http://192.168.0.202:8001/docs │ │ │ │ ※ 반드시 브라우저에서 변경사항 확인! │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Step 4: 운영 승격 (수동) │ ├─────────────────────────────────────────────────────────────────────────────┤ │ $ ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh promote" │ │ │ │ [실행 내용] │ │ 1. 현재 운영 버전 → /opt/autonet/releases/에 백업 │ │ 2. staging → production 으로 rsync 복사 │ │ ※ .env, *.db, uploads/ 는 제외 (preserve) │ │ 3. Docker 컨테이너 재빌드 및 시작 │ │ 4. 운영 서버 가동 (포트 3000, 8000) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Step 5: 운영 확인 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ https://autonetsellcar.com │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 3.2 배포 명령어 요약 ```bash # 1. 커밋 git add -A && git commit -m "변경 내용" # 2. 스테이징 배포 (자동) git push staging main # 3. 스테이징 확인 # 브라우저: http://192.168.0.202:3001 # 4. 운영 승격 (확인 후) ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh promote" ``` --- ## 4. 중요: 배포 시 보존되는 파일들 ### 4.1 rsync 제외 목록 (deploy.sh) `deploy.sh promote` 실행 시 다음 파일/폴더는 **복사되지 않음**: | 제외 항목 | 이유 | |----------|------| | `.env` | 환경변수 (DB접속정보, API키 등) - 서버별로 다름 | | `*.db` | SQLite 데이터베이스 (현재 미사용이지만 안전상) | | `uploads/` | 업로드된 파일 (PDF, 이미지 등) | ### 4.2 .env 파일 관리 (매우 중요!) ``` /opt/autonet/staging/backend/.env ← 스테이징용 .env /opt/autonet/production/backend/.env ← 운영용 .env (절대 덮어쓰면 안됨!) ``` **핵심 원칙**: `.env` 파일은 서버에 직접 생성하고, 배포로 덮어쓰지 않음 --- ## 5. 데이터베이스 연결 ### 5.1 DB 아키텍처 ``` ┌─────────────────────┐ ┌─────────────────────┐ │ server2 (Docker) │ │ server1 │ │ │ │ │ │ autonet-backend ────┼────────►│ PostgreSQL :5432 │ │ │ TCP │ Database: autonet │ │ │ │ │ └─────────────────────┘ └─────────────────────┘ ``` ### 5.2 환경변수 (backend/.env) ```env # 필수 - DB가 server1에 있음! USE_SQLITE=False DB_HOST=192.168.0.201 DB_PORT=5432 DB_NAME=autonet DB_USER=admin DB_PASSWORD=roskfl@1122 ``` ### 5.3 DB 스키마 변경 시 PostgreSQL 직접 접속하여 ALTER TABLE 실행: ```bash # server1에서 직접 실행 psql -U admin -d autonet -c "ALTER TABLE users ADD COLUMN new_column VARCHAR(100);" # 또는 server2에서 원격 실행 ssh damon@192.168.0.202 "docker exec autonet-backend python -c \" from app.database import engine from sqlalchemy import text with engine.connect() as conn: conn.execute(text('ALTER TABLE users ADD COLUMN new_column VARCHAR(100)')) conn.commit() \"" ``` --- ## 6. 롤백 ```bash # 직전 버전으로 롤백 ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh rollback" # 특정 버전으로 롤백 ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh rollback-to 20260101_211517" # 릴리즈 목록 확인 ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh status" ``` --- ## 7. 서버 상태 확인 ```bash # 컨테이너 상태 ssh damon@192.168.0.202 "docker ps" # 백엔드 로그 ssh damon@192.168.0.202 "docker logs autonet-backend --tail 50" # 프론트엔드 로그 ssh damon@192.168.0.202 "docker logs autonet-frontend --tail 50" # 환경변수 확인 (DB 연결 설정) ssh damon@192.168.0.202 "docker exec autonet-backend python -c \" import os print('USE_SQLITE:', os.getenv('USE_SQLITE')) print('DB_HOST:', os.getenv('DB_HOST')) \"" ``` --- ## 8. 절대 하지 말아야 할 것들 ### 8.1 .env 파일 관련 | 금지 사항 | 이유 | 올바른 방법 | |----------|------|------------| | `.env`를 git에 커밋 | 보안 위험 | `.gitignore`에 포함됨 | | 운영서버 `.env` 직접 삭제 | 서비스 중단 | 백업 후 수정 | | docker-compose에서 `.env` 볼륨 마운트 | 파일/디렉토리 혼동 | `env_file:` 사용 | ### 8.2 이전에 발생한 실수와 해결책 #### 실수 1: .env가 디렉토리로 생성됨 **증상**: - 로그인 실패 - `(sqlite3.OperationalError) no such column` 에러 - 이메일 발송 안됨 **원인**: - docker-compose에서 `.env`를 볼륨으로 마운트할 때, 파일이 없으면 디렉토리로 생성됨 - 환경변수 로드 실패 → `USE_SQLITE=True` 기본값 사용 → SQLite 사용 시도 **해결**: ```bash # 1. .env가 디렉토리인지 확인 ssh damon@192.168.0.202 "ls -la /opt/autonet/production/backend/.env" # 2. 디렉토리면 삭제 ssh damon@192.168.0.202 "rm -rf /opt/autonet/production/backend/.env" # 3. 파일로 생성 ssh damon@192.168.0.202 "cat > /opt/autonet/production/backend/.env << 'EOF' USE_SQLITE=False DB_HOST=192.168.0.201 DB_PORT=5432 DB_NAME=autonet DB_USER=admin DB_PASSWORD=roskfl@1122 # ... 나머지 환경변수 EOF" # 4. 컨테이너 재시작 ssh damon@192.168.0.202 "cd /opt/autonet/production && docker-compose -f docker-compose.production.yml up -d --force-recreate" ``` **예방책** (이미 적용됨): - `docker-compose.production.yml`에서 `env_file:` 사용 (볼륨 마운트 대신) - `deploy.sh`에서 `.env` rsync 제외 --- ## 9. 필수 환경변수 목록 | 변수 | 설명 | 필수 | |------|------|------| | `USE_SQLITE` | `False` (PostgreSQL 사용) | ★ | | `DB_HOST` | `192.168.0.201` | ★ | | `DB_PORT` | `5432` | ★ | | `DB_NAME` | `autonet` | ★ | | `DB_USER` | `admin` | ★ | | `DB_PASSWORD` | (비밀번호) | ★ | | `SMTP_USER` | Gmail 계정 | ★ | | `SMTP_PASSWORD` | 앱 비밀번호 (16자리) | ★ | | `AZURE_TRANSLATOR_KEY` | Azure 번역 API 키 | ★ | | `STRIPE_SECRET_KEY` | Stripe 결제 키 | 선택 | --- ## 10. SSH 키 설정 ```powershell # server4에서 공개키 확인 cat ~/.ssh/id_ed25519.pub # server2에 등록 ssh damon@192.168.0.202 "echo '공개키내용' >> ~/.ssh/authorized_keys" ``` --- ## 11. 변경 이력 | 날짜 | 변경 내용 | DB 변경 | |------|----------|---------| | 2026-01-01 | Cost 페이지 배경색/폭 통일 | - | | 2026-01-01 | .env 파일 문제 해결, deploy.sh rsync에서 .env 제외, docker-compose env_file 방식 | - | | 2026-01-01 | 강력한 비밀번호 정책 및 로그인 보안 강화 | users: failed_login_attempts, locked_until, password_reset_required | | 2026-01-01 | 삭제된 사용자 재가입 허용 수정 | - | | 2026-01-01 | inquiries 테이블 누락 컬럼 추가 | inquiries: category, subject 등 8개 컬럼 | | 2026-01-01 | 운영서버 .env 파일 생성 (SMTP 설정) | - | | 2026-01-01 | cc_per_banner_view 설정 추가 | system_settings.cc_per_banner_view (REAL) | --- ## 12. 빠른 참조 (Quick Reference) ### 일반 배포 ```bash git add -A && git commit -m "메시지" git push staging main # 스테이징 확인: http://192.168.0.202:3001 ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh promote" ``` ### 롤백 ```bash ssh damon@192.168.0.202 "/opt/autonet/scripts/deploy.sh rollback" ``` ### 로그 확인 ```bash ssh damon@192.168.0.202 "docker logs autonet-backend --tail 50" ``` ### .env 문제 시 ```bash ssh damon@192.168.0.202 "ls -la /opt/autonet/production/backend/.env" # 디렉토리면 삭제 후 파일로 재생성 ``` --- **이 문서는 새 세션 시작 시 CLAUDE.md와 함께 반드시 읽어주세요!**