# Node.js 배포 가이드

> **대상**: `node-service/` 내 4개 서비스 (blockchain-api, relayer-api, wallet-activator, telegram-bot)
> **서버**: Ubuntu VPS/EC2 + PM2
> **CI/CD**: GitLab CI (repo 루트 `.gitlab-ci.yml`)

---

## 1. 생성된 파일 목록

| 파일 | 위치 | 역할 |
|------|------|------|
| `ecosystem.config.cjs` | `node-service/` | PM2 프로세스 설정 (4개 서비스) |
| `deploy.sh` | `node-service/` | 수동 배포 스크립트 (셸) |
| `.gitlab-ci.yml` | repo 루트 (`/`) | GitLab CI/CD 파이프라인 |

---

## 2. 서버 초기 셋업

### 2-1. 스크립트로 자동 셋업

```bash
cd /opt/cryptoments/node-service
./deploy.sh --setup
```

설치 항목: Node.js 20 (fnm), pnpm 9, PM2, 로그 로테이션 (50MB/14일), systemd startup

### 2-2. 수동 셋업 (참고)

```bash
# Node.js 20 (fnm)
curl -fsSL https://fnm.vercel.app/install | bash
fnm install 20 && fnm use 20 && fnm default 20

# pnpm + PM2
npm install -g pnpm pm2

# PM2 로그 로테이션
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 14
pm2 set pm2-logrotate:compress true

# 시스템 부팅 시 자동 시작
pm2 startup systemd -u deploy --hp /home/deploy
```

### 2-3. .env 설정

```bash
cp .env.example .env
vi .env   # 운영 환경 값 입력
```

필수 항목: `DB_PASSWORD`, `KMS_LOCAL_KEY`, `TELEGRAM_BOT_TOKEN`, `TRONZAP_API_TOKEN`, `TRONZAP_API_SECRET`

---

## 3. 수동 배포 (deploy.sh)

### 전체 배포

```bash
cd /opt/cryptoments/node-service
./deploy.sh
```

실행 순서: git pull → pnpm install → common 빌드 → 서비스 빌드 → PM2 reload → 헬스체크

### 주요 옵션

```bash
./deploy.sh                          # 전체 배포
./deploy.sh --only blockchain-api    # 단일 서비스
./deploy.sh --only api               # API 서비스만 (blockchain-api + relayer-api)
./deploy.sh --only workers           # Worker만 (wallet-activator + telegram-bot)
./deploy.sh --build-only             # 빌드만 (PM2 재시작 안함)
./deploy.sh --restart-only           # PM2 재시작만
./deploy.sh --rollback               # 이전 커밋으로 롤백
./deploy.sh --status                 # 현재 상태 확인
```

### 환경변수

```bash
DEPLOY_BRANCH=develop ./deploy.sh    # develop 브랜치 배포
DEPLOY_ENV=staging ./deploy.sh       # staging 환경
SKIP_PULL=1 ./deploy.sh              # git pull 건너뜀
```

---

## 4. GitLab CI/CD 파이프라인

### 4-1. 파이프라인 구조

```
cryptoments-backend (모노레포)
├── .gitlab-ci.yml          ← GitLab 이 읽는 파일
├── build.gradle            ← Spring Boot (향후 CI 추가)
└── node-service/           ← Node.js (현재 CI 활성)
```

### 4-2. 파이프라인 흐름

```
node-service/** 변경 감지
   ↓
install → build → lint (병렬)
   ↓        ↓
   ↓     deploy-staging  (develop 브랜치 → 자동)
   ↓     deploy-production (main 브랜치 → 수동 승인)
```

### 4-3. GitLab 변수 설정

Settings → CI/CD → Variables 에서 추가:

| 변수 | 타입 | 값 예시 | 비고 |
|------|------|---------|------|
| `NODE_DEPLOY_HOST` | Variable | `10.0.1.100` | 배포 서버 IP |
| `NODE_DEPLOY_USER` | Variable | `deploy` | SSH 사용자 |
| `NODE_DEPLOY_PATH` | Variable | `/opt/cryptoments/node-service` | 서버 내 경로 |
| `SSH_PRIVATE_KEY` | File | (SSH 개인키 내용) | 배포 서버 접속용 |

### 4-4. 변경 감지 규칙

| 조건 | 트리거 |
|------|--------|
| `node-service/**` 변경 + develop push | Staging 자동 배포 |
| `node-service/**` 변경 + main push | Production 수동 배포 (버튼 클릭) |
| `node-v*` 태그 | Production 수동 배포 |
| feature 브랜치 | 빌드 + 린트만 (배포 안함) |
| Spring Boot 파일만 변경 | Node.js 파이프라인 스킵 |

### 4-5. 태그 기반 배포 예시

```bash
git tag node-v1.0.0
git push origin node-v1.0.0
# → GitLab에서 deploy-production 수동 실행 버튼 클릭
```

---

## 5. PM2 운영 명령어

```bash
pm2 list                     # 전체 상태
pm2 logs                     # 실시간 로그 (전체)
pm2 logs blockchain-api      # 특정 서비스 로그
pm2 monit                    # CPU/메모리 모니터링

pm2 restart all              # 전체 재시작
pm2 restart blockchain-api   # 특정 서비스 재시작
pm2 reload ecosystem.config.cjs  # 0-downtime reload

pm2 stop all                 # 전체 중지
pm2 delete all               # 전체 프로세스 제거

pm2 save                     # 현재 프로세스 목록 저장
pm2 resurrect                # 저장된 목록 복원
```

---

## 6. 서비스별 설정

| 서비스 | 포트 | 메모리 제한 | 특이사항 |
|--------|------|------------|---------|
| blockchain-api | 3001 | 512MB | REST API, 헬스체크 `/ping` |
| relayer-api | 3002 | 512MB | REST API + Poller, 헬스체크 `/ping` |
| wallet-activator | — | 256MB | Worker, 매일 04:00 자동 재시작 |
| telegram-bot | — | 256MB | Worker, long-polling |

---

## 7. 로그 관리

```
node-service/logs/
├── blockchain-api-out.log       # stdout
├── blockchain-api-error.log     # stderr
├── relayer-api-out.log
├── relayer-api-error.log
├── wallet-activator-out.log
├── wallet-activator-error.log
├── telegram-bot-out.log
└── telegram-bot-error.log
```

PM2 로그 로테이션: 50MB 초과 시 자동 분할, 14일 보관, gzip 압축.

---

## 8. 롤백

### deploy.sh 롤백

```bash
./deploy.sh --rollback
# → git checkout HEAD~1 → rebuild → PM2 reload
```

### GitLab CI 롤백

GitLab → Pipelines → 이전 성공 파이프라인 → deploy job 재실행 (Retry)

### 수동 롤백

```bash
cd /opt/cryptoments/node-service
git log --oneline -10            # 이전 커밋 확인
git checkout <commit-hash> -- .  # 특정 커밋으로 복원
pnpm install --frozen-lockfile --prod
pnpm -r build
pm2 reload ecosystem.config.cjs
```

---

## 9. 서버 디렉토리 구조 (배포 후)

```
/opt/cryptoments/node-service/
├── .env                        # 서버에만 존재 (rsync 제외)
├── ecosystem.config.cjs        # PM2 설정
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── node_modules/               # pnpm install --prod 결과
├── logs/                       # PM2 로그
└── packages/
    ├── common/
    │   ├── dist/               # 빌드 결과물
    │   └── package.json
    ├── blockchain-api/
    │   ├── dist/app.js         # 실행 엔트리포인트
    │   └── package.json
    ├── relayer-api/
    │   ├── dist/app.js
    │   └── package.json
    ├── wallet-activator/
    │   ├── dist/app.js
    │   └── package.json
    └── telegram-bot/
        ├── dist/app.js
        └── package.json
```

소스 코드(`.ts`, `src/`)는 서버에 배포되지 않음. `dist/` 빌드 결과물만 전송.
