# Tasteby 환경 관리 가이드

## 환경 구성 개요

```
┌─────────────────────────────────────────────────────────────┐
│                        개발 (Local)                          │
│                                                              │
│  backend/.env          ← 백엔드 환경변수 (DB, OCI, Google)   │
│  frontend/.env.local   ← 프론트엔드 환경변수 (NEXT_PUBLIC_*) │
│  ~/.oci/config         ← OCI API 인증 (로컬 경로)            │
│  Oracle Wallet 디렉토리 ← DB mTLS 인증 (로컬 경로)           │
│                                                              │
│  PM2 → start.sh → source backend/.env → gradlew bootRun     │
│  PM2 → npm run dev (Next.js, .env.local 자동 로드)           │
│  Redis → 192.168.0.147:6379 (로컬 네트워크)                  │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                       운영 (OKE)                             │
│                                                              │
│  k8s/configmap.yaml    ← 비밀이 아닌 설정 (Redis host 등)    │
│  k8s/secrets.yaml      ← 민감 정보 (DB, JWT, API keys)      │
│  Secret: oracle-wallet  ← DB mTLS 인증 (Volume 마운트)       │
│  Secret: oci-config     ← OCI API 인증 (Volume 마운트)       │
│                                                              │
│  Pod → envFrom: ConfigMap + Secret → application.yml 참조    │
│  Redis → redis:6379 (K8s Service DNS, 클러스터 내부)          │
└─────────────────────────────────────────────────────────────┘
```

## 환경변수 전체 목록

### 백엔드 (application.yml에서 참조)

| 변수명 | 설명 | 민감 | 개발 | 운영 |
|--------|------|:----:|------|------|
| `ORACLE_USER` | DB 사용자명 | ✅ | backend/.env | Secret |
| `ORACLE_PASSWORD` | DB 비밀번호 | ✅ | backend/.env | Secret |
| `ORACLE_DSN` | TNS 연결 문자열 | ✅ | backend/.env | Secret |
| `ORACLE_WALLET` | Wallet 디렉토리 경로 | | backend/.env | ConfigMap → `/etc/oracle/wallet` |
| `JWT_SECRET` | JWT 서명 키 | ✅ | 기본값 사용 | Secret |
| `OCI_COMPARTMENT_ID` | OCI 컴파트먼트 ID | ✅ | backend/.env | Secret |
| `OCI_CHAT_ENDPOINT` | GenAI Chat 엔드포인트 | | backend/.env | ConfigMap |
| `OCI_GENAI_ENDPOINT` | GenAI Embed 엔드포인트 | | backend/.env | ConfigMap |
| `OCI_CHAT_MODEL_ID` | Chat 모델 ID | ✅ | backend/.env | Secret |
| `OCI_EMBED_MODEL_ID` | Embed 모델 ID | | backend/.env | ConfigMap |
| `GOOGLE_MAPS_API_KEY` | Google Maps API 키 | ✅ | backend/.env | Secret |
| `YOUTUBE_DATA_API_KEY` | YouTube Data API 키 | ✅ | backend/.env | Secret |
| `GOOGLE_CLIENT_ID` | Google OAuth 클라이언트 ID | | 기본값 사용 | ConfigMap |
| `REDIS_HOST` | Redis 호스트 | | 기본값 `192.168.0.147` | ConfigMap → `redis` |
| `REDIS_PORT` | Redis 포트 | | 기본값 `6379` | ConfigMap |
| `REDIS_DB` | Redis DB 번호 | | 기본값 `0` | ConfigMap |

### 프론트엔드 (빌드 시 주입)

| 변수명 | 설명 | 개발 | 운영 |
|--------|------|------|------|
| `NEXT_PUBLIC_API_URL` | API 기본 URL | `.env.local` → 빈값 (상대경로) | Docker build arg → 빈값 |
| `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY` | Maps API 키 | `.env.local` | Docker build arg |
| `NEXT_PUBLIC_GOOGLE_CLIENT_ID` | OAuth 클라이언트 ID | `.env.local` | Docker build arg |

> **참고**: `NEXT_PUBLIC_*` 변수는 Next.js 빌드 시 코드에 인라인되므로,
> 런타임이 아닌 Docker 빌드 시점에 주입해야 합니다.

## 개발 vs 운영 차이점

### Redis 연결

```
개발: REDIS_HOST=192.168.0.147 (로컬 네트워크 IP, 기본값)
운영: REDIS_HOST=redis          (K8s Service DNS, ConfigMap)
```

K8s에서 Service 이름 `redis`는 클러스터 내부 DNS로 자동 해석됩니다.
Pod IP가 변경되어도 Service가 항상 올바른 Pod를 가리킵니다.

```
redis (Service, ClusterIP)
  └─ selector: app=redis
      └─ redis Pod (IP 자동 할당, 변경되어도 Service가 추적)
```

### OCI 인증

```
개발: ~/.oci/config → 로컬 PEM 파일 경로
운영: /root/.oci/config → Secret Volume 마운트
     /root/.oci/oci_api_key.pem → Secret Volume 마운트
```

운영용 OCI config 파일은 `key_file` 경로를 컨테이너 내부로 변경해야 합니다:
```ini
[DEFAULT]
user=ocid1.user.oc1..xxx
fingerprint=xx:xx:xx
key_file=/root/.oci/oci_api_key.pem    ← 컨테이너 내부 경로
tenancy=ocid1.tenancy.oc1..xxx
region=ap-seoul-1
```

### Oracle DB 연결

```
개발: ORACLE_WALLET=/Users/joungmin/.../Wallet_xxx (로컬 경로)
      ORACLE_DSN=tasteby_high?TNS_ADMIN=/Users/joungmin/.../Wallet_xxx
운영: ORACLE_WALLET=/etc/oracle/wallet (Secret Volume 마운트 경로)
      ORACLE_DSN=tasteby_high?TNS_ADMIN=/etc/oracle/wallet
```

## 환경별 설정 파일 매핑

```
┌──────────────────┬──────────────────────┬──────────────────────────┐
│     설정 항목     │    개발 (Local)       │       운영 (OKE)          │
├──────────────────┼──────────────────────┼──────────────────────────┤
│ 백엔드 환경변수   │ backend/.env          │ k8s/configmap.yaml       │
│                  │ (start.sh에서 source)  │ k8s/secrets.yaml         │
├──────────────────┼──────────────────────┼──────────────────────────┤
│ 프론트엔드 환경변수│ frontend/.env.local   │ Dockerfile build args    │
│                  │ (Next.js 자동 로드)    │ (deploy.sh에서 주입)      │
├──────────────────┼──────────────────────┼──────────────────────────┤
│ OCI 인증         │ ~/.oci/config         │ Secret: oci-config       │
│                  │ (로컬 PEM 경로)        │ (Volume → /root/.oci/)   │
├──────────────────┼──────────────────────┼──────────────────────────┤
│ Oracle Wallet    │ 로컬 Wallet 디렉토리   │ Secret: oracle-wallet    │
│                  │                      │ (Volume → /etc/oracle/   │
│                  │                      │  wallet/)                │
├──────────────────┼──────────────────────┼──────────────────────────┤
│ Redis            │ 192.168.0.147:6379   │ redis:6379               │
│                  │ (로컬 네트워크)        │ (K8s Service DNS)        │
├──────────────────┼──────────────────────┼──────────────────────────┤
│ 웹서버/SSL       │ nginx + Let's Encrypt │ Ingress + cert-manager   │
│                  │ (로컬 certbot)         │ (자동 발급/갱신)          │
└──────────────────┴──────────────────────┴──────────────────────────┘
```

## 시크릿 관리 원칙

1. **secrets.yaml은 git에 올리지 않음** — `.gitignore`에 포함
2. **secrets.yaml.template만 git에 올림** — 키 이름 + 구조만 공유
3. **운영 시크릿 변경 시**:
   ```bash
   # secrets.yaml 수정 후
   kubectl apply -f k8s/secrets.yaml
   kubectl rollout restart deployment/backend -n tasteby
   ```
4. **파일 기반 시크릿(Wallet, OCI config)은 kubectl로 직접 생성**:
   ```bash
   kubectl create secret generic oracle-wallet --from-file=... -n tasteby
   kubectl create secret generic oci-config --from-file=... -n tasteby
   ```

## application.yml의 환경변수 바인딩

Spring Boot의 `application.yml`이 환경변수를 자동으로 읽습니다:

```yaml
spring:
  datasource:
    url: jdbc:oracle:thin:@${ORACLE_DSN}       # ← Secret에서 주입
  data:
    redis:
      host: ${REDIS_HOST:192.168.0.147}         # ← ConfigMap에서 주입, 개발은 기본값
app:
  oci:
    compartment-id: ${OCI_COMPARTMENT_ID}       # ← Secret에서 주입
```

K8s에서는 `envFrom`으로 ConfigMap과 Secret의 모든 키-값이 환경변수로 들어갑니다:

```yaml
# backend-deployment.yaml
envFrom:
  - configMapRef:
      name: tasteby-config     # REDIS_HOST, REDIS_PORT, ...
  - secretRef:
      name: tasteby-secrets    # ORACLE_USER, ORACLE_PASSWORD, ...
```

개발 환경에서는 동일한 변수명이 `backend/.env`에서 `source`로 로드됩니다.
**변수명이 동일하므로 코드 변경 없이 환경만 바꿀 수 있습니다.**
