> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casebender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# DigitalOcean에 배포하기

> DigitalOcean에 CaseBender 배포하기

## 개요

이 가이드는 사전 구축된 Docker 이미지를 사용하여 Kubernetes(DOKS) 및 관리형 서비스로 DigitalOcean에 CaseBender를 배포하는 과정을 안내합니다.

## 사전 요구 사항

1. [DigitalOcean 계정](https://cloud.digitalocean.com/)
2. [doctl](https://docs.digitalocean.com/reference/doctl/how-to/install/) CLI 설치
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) 설치
4. [Docker](https://docs.docker.com/get-docker/) 설치

## 1단계: 초기 설정

### doctl 설치 및 구성

<CodeGroup>
  ```bash macOS theme={null}
  # Homebrew 사용
  brew install doctl

  # API 토큰으로 인증

  doctl auth init

  # Container Registry용 Docker 구성

  doctl registry login

  ```

  ```bash Linux theme={null}
  # 최신 릴리스 다운로드
  cd ~/Downloads
  wget https://github.com/digitalocean/doctl/releases/download/v1.XX.X/doctl-1.XX.X-linux-amd64.tar.gz

  # 압축 해제 및 경로 이동
  tar xf ~/Downloads/doctl-1.XX.X-linux-amd64.tar.gz
  sudo mv ~/Downloads/doctl /usr/local/bin

  # API 토큰으로 인증
  doctl auth init

  # Container Registry용 Docker 구성
  doctl registry login
  ```

  ```powershell Windows theme={null}
  # Chocolatey 사용
  choco install doctl

  # API 토큰으로 인증
  doctl auth init

  # Container Registry용 Docker 구성
  doctl registry login
  ```
</CodeGroup>

## 2단계: Kubernetes 클러스터 생성

```bash theme={null}
# DOKS 클러스터 생성
doctl kubernetes cluster create casebender \
  --region nyc1 \
  --size s-2vcpu-4gb \
  --count 3 \
  --version latest

# kubeconfig 가져오기
doctl kubernetes cluster kubeconfig save casebender
```

## 3단계: 관리형 서비스 설정

### 객체 스토리지용 Spaces 생성

```bash theme={null}
# Spaces 버킷 생성
doctl spaces create casebender-storage \
  --region nyc3

# Spaces 액세스 키 생성
doctl spaces access-key create

# 참고: 액세스 키와 시크릿 키를 안전하게 저장하세요
# 애플리케이션 구성에 필요합니다
```

### 관리형 PostgreSQL 생성

```bash theme={null}
# 데이터베이스 클러스터 생성
doctl databases create \
  --engine pg \
  --name casebender-db \
  --region nyc1 \
  --size db-s-2vcpu-4gb \
  --version 14 \
  --num-nodes 1

# 데이터베이스 생성
doctl databases db create casebender-db casebender

# 연결 세부 정보 가져오기
doctl databases connection casebender-db --format ConnectionString
```

### 관리형 Redis 생성

```bash theme={null}
# Redis 클러스터 생성
doctl databases create \
  --engine redis \
  --name casebender-redis \
  --region nyc1 \
  --size db-s-1vcpu-2gb \
  --version 7

# 연결 세부 정보 가져오기
doctl databases connection casebender-redis --format ConnectionString
```

## 4단계: 컨테이너 레지스트리 구성

```bash theme={null}
# 컨테이너 레지스트리 생성
doctl registry create casebender-registry

# 레지스트리 엔드포인트 가져오기
REGISTRY_ENDPOINT=$(doctl registry get-endpoint)

# CaseBender 이미지 가져오기
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/misp-processor:latest

# 레지스트리용 이미지 태그 지정
docker tag casebender/casebender:latest registry.digitalocean.com/casebender-registry/app:latest
docker tag casebender/workflow-processor:latest registry.digitalocean.com/casebender-registry/workflow-processor:latest
docker tag casebender/misp-processor:latest registry.digitalocean.com/casebender-registry/misp-processor:latest

# 이미지 푸시
docker push registry.digitalocean.com/casebender-registry/app:latest
docker push registry.digitalocean.com/casebender-registry/workflow-processor:latest
docker push registry.digitalocean.com/casebender-registry/misp-processor:latest

# Kubernetes 클러스터에 레지스트리 추가
doctl kubernetes cluster registry add casebender
```

## 5단계: Kubernetes에 배포

### 네임스페이스 생성

```bash theme={null}
kubectl create namespace casebender
```

### 시크릿 생성

```bash theme={null}
# 데이터베이스 및 Redis용 시크릿 생성
kubectl create secret generic db-credentials \
  --namespace casebender \
  --from-literal=postgres-url="postgresql://doadmin:password@casebender-db-do-user-1234567-0.b.db.ondigitalocean.com:25060/casebender?sslmode=require" \
  --from-literal=redis-url="rediss://default:password@casebender-redis-do-user-1234567-0.b.db.ondigitalocean.com:25061"

# 애플리케이션용 시크릿 생성
kubectl create secret generic app-secrets \
  --namespace casebender \
  --from-literal=auth-secret="your-auth-secret" \
  --from-literal=auth-salt="your-auth-salt"
```

### 애플리케이션 배포

`deployment.yaml` 생성:

```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: casebender-app
  namespace: casebender
spec:
  replicas: 2
  selector:
    matchLabels:
      app: casebender-app
  template:
    metadata:
      labels:
        app: casebender-app
    spec:
      containers:
        - name: app
          image: registry.digitalocean.com/casebender-registry/app:latest
          ports:
            - containerPort: 3000
          env:
            - name: AUTH_SECRET
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: auth-secret
            - name: AUTH_SALT
              valueFrom:
                secretKeyRef:
                  name: app-secrets
                  key: auth-salt
            - name: POSTGRES_PRISMA_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: postgres-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: redis-url
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: workflow-processor
  namespace: casebender
spec:
  replicas: 1
  selector:
    matchLabels:
      app: workflow-processor
  template:
    metadata:
      labels:
        app: workflow-processor
    spec:
      containers:
        - name: processor
          image: registry.digitalocean.com/casebender-registry/workflow-processor:latest
          env:
            - name: POSTGRES_PRISMA_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: postgres-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: redis-url
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: misp-processor
  namespace: casebender
spec:
  replicas: 1
  selector:
    matchLabels:
      app: misp-processor
  template:
    metadata:
      labels:
        app: misp-processor
    spec:
      containers:
        - name: processor
          image: registry.digitalocean.com/casebender-registry/misp-processor:latest
          env:
            - name: POSTGRES_PRISMA_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: postgres-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: redis-url
```

배포 적용:

```bash theme={null}
kubectl apply -f deployment.yaml
```

### 서비스 생성

`service.yaml` 생성:

```yaml theme={null}
apiVersion: v1
kind: Service
metadata:
  name: casebender-app
  namespace: casebender
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 3000
  selector:
    app: casebender-app
```

서비스 적용:

```bash theme={null}
kubectl apply -f service.yaml
```

## 7단계: 인그레스 설정

### NGINX 인그레스 컨트롤러 설치

```bash theme={null}
# Helm 리포지토리 추가
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# NGINX 인그레스 컨트롤러 설치
helm install nginx-ingress ingress-nginx/ingress-nginx \
  --namespace casebender \
  --set controller.publishService.enabled=true
```

### 인그레스 구성

`ingress.yaml` 생성:

```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: casebender-ingress
  namespace: casebender
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - your-domain.com
      secretName: casebender-tls
  rules:
    - host: your-domain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: casebender-app
                port:
                  number: 80
```

인그레스 적용:

```bash theme={null}
kubectl apply -f ingress.yaml
```

## 8단계: cert-manager로 SSL 설정

```bash theme={null}
# cert-manager 설치
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml

# ClusterIssuer 생성
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@domain.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
EOF
```

## 모니터링 및 유지 관리

### 모니터링 설정

```bash theme={null}
# 메트릭 서버 설치
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Prometheus 및 Grafana 배포
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace
```

### 수평 Pod 자동 확장 구성

`hpa.yaml` 생성:

```yaml theme={null}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: casebender-app-hpa
  namespace: casebender
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: casebender-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 80
```

HPA 적용:

```bash theme={null}
kubectl apply -f hpa.yaml
```

## 백업 및 재해 복구

### 데이터베이스 백업

DigitalOcean 관리형 데이터베이스는 자동으로 백업을 처리합니다. 또한 다음을 수행할 수 있습니다:

```bash theme={null}
# 수동 백업 생성
doctl databases backup casebender-db
```

### 데이터베이스 장애 조치 구성

```bash theme={null}
# 자동 장애 조치 활성화
doctl databases replica casebender-db create \
  --region sfo2
```

## 보안 모범 사례

1. DigitalOcean Cloud Firewall 활성화
2. 프라이빗 네트워킹 사용
3. 네트워크 정책 구현
4. 정기적인 보안 업데이트
5. 감사 로깅 활성화

## 비용 최적화

1. 적절한 노드 크기 사용
2. 자동 확장 구현
3. 블록 스토리지 현명하게 사용
4. 리소스 사용량 모니터링
5. 예약 드롭릿 고려

## 다음 단계

* CI/CD 파이프라인 설정
* 모니터링 경고 구성
* 로깅 솔루션 구현
* 보안 조치 검토
