CCG-Platform Cross-Repo 분석
메인 인덱스 | CCG-Platform | GitHub Org
요약
이 문서는 CCG-Platform 조직의 12개 저장소에 대한 종합적인 분석을 제공하며, 의존 관계, 데이터 흐름, 배포 설정 및 공통 인프라를 문서화합니다.
최종 업데이트: 2026년 3월 26일
목차
다이어그램 작성 원칙: 세로형 Mermaid 가이드
1. 저장소 개요
1.1 저장소 목록 (총 12개 클론 디렉터리)
| # | 저장소 | 유형 | 목적 | 언어/프레임워크 |
|---|---|---|---|---|
| 1 | portal-backend | 메인 플랫폼 | 사용자 포털, 인증, 과금 | Python/FastAPI |
| 2 | CCGP-ui | 프론트엔드 | 웹 사용자 인터페이스 | React/JavaScript |
| 3 | CCG-Platform | 조직용 placeholder | README placeholder | Markdown |
| 4 | PodManager | 컨테이너 관리 | K8s pod 관리 (v1) | Python/FastAPI |
| 5 | PodManager_V2 | 컨테이너 관리 | K8s pod 관리 (v2 - 프로덕션) | Python/FastAPI |
| 6 | game-container | 컨테이너 이미지 | Steam 게임 컨테이너 이미지 | Docker |
| 7 | TerraformLearn | 인프라 | AWS EKS infrastructure as code | Terraform |
| 8 | k8s-setup-script | 인프라 | Kubernetes 설정 스크립트 | YAML/Shell |
| 9 | Selkies | 스트리밍 | WebRTC 스트리밍 컴포넌트 | Kubernetes |
| 10 | POC | 개념 증명 | SteamOS 개념 증명 | Docker Compose |
| 11 | demo | 데모 | 포털 데모 배포 | Kubernetes |
| 12 | Document | 문서 | 프로젝트 문서 | Markdown |
1.2 저장소 분류
flowchart TB subgraph Platform["CCG-Platform 아키텍처"] subgraph Presentation["표현 계층"] UI["CCGP-ui<br/>React 프론트엔드<br/>Port 3004<br/>VITE_API_URL"] end subgraph API["API 계층"] Portal["portal-backend<br/>Port 8000<br/>사용자 인증 및 관리<br/>과금 및 트랜잭션<br/>Workspace 임대 관리"] PodMgr["PodManager_V2<br/>Port 8000<br/>Pod 수명주기 관리<br/>K8s 리소스 오케스트레이션<br/>Workspace 라우팅<br/>NetworkPolicy 관리"] end subgraph Container["컨테이너 계층"] Game["game-container<br/>Steam 클라이언트<br/>Selkies-GStreamer WebRTC<br/>NVIDIA GPU 지원"] end subgraph Infra["인프라 계층"] EKS["AWS EKS<br/>EKS 1.33"] Traefik["Traefik<br/>Ingress"] Karpenter["Karpenter<br/>Auto-scaler"] GPU["NVIDIA GPU Operator"] Redis["Redis<br/>Cache"] Postgres["PostgreSQL<br/>implied"] end end UI --> Portal Portal --> PodMgr PodMgr --> Game PodMgr --> EKS PodMgr --> Traefik EKS --> Karpenter EKS --> GPU Portal --> Redis Portal --> Postgres
2. 의존 관계 매핑
2.1 서비스 의존 관계
flowchart TB UI["CCGP-ui<br/>프론트엔드"] Portal["portal-backend<br/>Port 8000<br/>FastAPI 웹 프레임워크<br/>SQLAlchemy ORM<br/>Celery + Redis<br/>Flower"] PodMgr["PodManager_V2<br/>Port 8000<br/>FastAPI 웹 프레임워크<br/>Kubernetes Python 클라이언트<br/>동적 IngressRoute 생성<br/>NetworkPolicy 관리"] EKS["AWS EKS + Karpenter<br/>K8s API Server<br/>노드 자동 프로비저닝<br/>NVIDIA GPU Operator<br/>Traefik Ingress Controller"] UserPods["사용자 Pods<br/>game-container 이미지<br/>Selkies WebRTC 스트리밍<br/>Steam 클라이언트<br/>TURN Server (coturn)"] UI --> Portal Portal -->|"HTTP API Call<br/>POD_CONTROLLER_SERVICE"| PodMgr PodMgr -->|"Kubernetes API"| EKS EKS -->|"동적 생성"| UserPods
2.2 컨테이너 이미지 의존 관계
flowchart TB subgraph Nvidia["NVIDIA 베이스 이미지"] NvidiaBase["ghcr.io/selkies-project/nvidia-egl-desktop:latest"] GameDocker["game-container/Dockerfile<br/>FROM nvidia-egl-desktop"] Steam["steam"] Supervisor["supervisord_steam.conf"] NvidiaBase --> GameDocker GameDocker --> Steam GameDocker --> Supervisor end subgraph Python["Python 베이스 이미지"] PythonBase["python:3.11-slim<br/>또는 유사"] PortalDocker["portal-backend/Dockerfile<br/>FastAPI<br/>Celery<br/>SQLAlchemy"] ManagerDocker["PodManager_V2/manager/Dockerfile<br/>FastAPI<br/>Kubernetes 클라이언트"] UserAppDocker["PodManager_V2/user-app/Dockerfile<br/>사용자 Workspace 베이스"] PythonBase --> PortalDocker PythonBase --> ManagerDocker PythonBase --> UserAppDocker end subgraph Turn["TURN 계열 이미지"] Coturn["ghcr.io/selkies-project/selkies-gstreamer/coturn:main<br/>Coturn TURN Server"] TurnRest["ghcr.io/selkies-project/selkies-gstreamer/turn-rest:main<br/>TURN REST API 인증"] end
2.3 외부 의존 관계
| 서비스 | 목적 | 사용하는 저장소 |
|---|---|---|
| AWS EKS | Kubernetes 클러스터 | TerraformLearn, 모든 서비스 |
| Redis | 캐시 및 Celery 브로커 | portal-backend |
| PostgreSQL | 주 데이터베이스 | portal-backend (암시적) |
| Cloudflare | DNS 및 SSL | TerraformLearn |
| NVIDIA GPU Operator | GPU 관리 | TerraformLearn (EKS) |
| Karpenter | 노드 자동 스케일링 | TerraformLearn |
| Traefik | Ingress 컨트롤러 | TerraformLearn, PodManager_V2 |
| Cert-Manager | SSL 인증서 관리 | TerraformLearn |
| ghcr.io | 컨테이너 레지스트리 | PodManager_V2, game-container |
| Selkies | WebRTC 스트리밍 | game-container |
| Coturn | TURN 서버 | game-container, Selkies |
3. 데이터 흐름 아키텍처
3.1 사용자 Workspace 생성 흐름
flowchart TB Start["사용자<br/>Workspace 생성 요청"] UI["CCGP-ui<br/>워크스페이스 생성 API 호출"] Portal["portal-backend<br/>잔액 검증<br/>임대 레코드 생성"] PodReq["PodManager_V2 호출<br/>Pod 생성 요청"] K8s["AWS EKS<br/>Pod / Service / Route / Policy 생성"] Scale["Karpenter<br/>필요 시 GPU 노드 확장"] Ready["Workspace 준비<br/>session_id / status / url 반환"] Cookie["portal-backend<br/>세션 쿠키 설정"] Access["사용자 접근<br/>workspace.ccgp.dev"] Route["Traefik<br/>세션 기준 라우팅"] Stream["사용자 Pod<br/>Selkies 스트리밍 시작"] Start --> UI UI --> Portal Portal --> PodReq PodReq --> K8s K8s --> Scale Scale --> Ready Ready --> Cookie Cookie --> Access Access --> Route Route --> Stream
3.2 API 데이터 흐름
flowchart TB UI["CCGP-ui<br/>브라우저 API 진입점"] Portal["portal-backend<br/>인증 / 과금 / 임대 API"] PodMgr["PodManager_V2<br/>Pod 제어 API"] K8s["AWS EKS<br/>Kubernetes API"] Resources["생성 리소스<br/>Pod / Service / IngressRoute / NetworkPolicy"] UI -->|"사용자 API 요청"| Portal Portal -->|"Pod 제어 요청"| PodMgr PodMgr -->|"Kubernetes 리소스 생성 / 조회 / 삭제"| K8s K8s --> Resources
주요 엔드포인트는 다이어그램에서 분리해 아래처럼 정리하는 편이 더 안정적으로 읽힙니다.
| 호출 구간 | 대표 엔드포인트 | 역할 |
|---|---|---|
CCGP-ui -> portal-backend | POST /api/v1/auth/login | 로그인 |
CCGP-ui -> portal-backend | POST /api/v1/workspaces | 워크스페이스 생성 |
CCGP-ui -> portal-backend | GET /api/v1/workspaces/my | 내 워크스페이스 조회 |
CCGP-ui -> portal-backend | DELETE /api/v1/workspaces/{rental_id} | 워크스페이스 종료 |
portal-backend -> PodManager_V2 | POST /api/v1/pods | Pod 생성 요청 |
portal-backend -> PodManager_V2 | GET /api/v1/pods/{session_id} | Pod 상태 조회 |
portal-backend -> PodManager_V2 | DELETE /api/v1/pods/{session_id} | Pod 삭제 요청 |
3.3 WebRTC 스트리밍 흐름
flowchart TB Browser["브라우저<br/>workspace.ccgp.dev 접속"] Traefik["Traefik<br/>세션 쿠키 기반 라우팅"] Workspace["사용자 Workspace Pod<br/>Selkies 웹 UI"] Game["game-container<br/>Selkies GStreamer"] Turn["coturn / turn-rest<br/>TURN 인증 및 중계"] Browser --> Traefik Traefik --> Workspace Workspace --> Game Game --> Turn Turn --> Browser
스트리밍 설정 메모:
SELKIES_ENCODER=nvh264encSELKIES_VIDEO_BITRATE=8000SELKIES_FRAMERATE=60SELKIES_TURN_REST_URI=http://turn-rest:8008
4. 배포 단위
4.1 Docker Compose 배포
# portal-backend/docker-compose.yml
서비스:
- portal-backend: Portal API (Port 8000)
- worker: Celery worker
- beat: Celery beat 스케줄러
- flower: Celery 모니터링 (Port 5555)
- redis: Redis 캐시 (Port 6379)
# CCGP-ui/docker-compose.yml
서비스:
- frontend: React 앱 (Port 3004)
# game-container/docker-compose.yml
서비스:
- game-container: Steam + Selkies (Port 8080)
- coturn: TURN 서버
- turn-rest: TURN 인증 서비스
# PodManager/docker/docker-compose.yml
서비스:
- traefik: Ingress 컨트롤러 (Port 80, 8080)
- manager: Pod manager API (Port 8000)
- user-app-builder: 사용자 앱 이미지 빌더
# POC/docker-compose.yaml
서비스:
- steamos: LinuxServer SteamOS 컨테이너 (POC)4.2 Kubernetes 배포
# PodManager_V2/k8s/ (프로덕션)
네임스페이스: pod-manager
리소스:
- manager-deployment.yaml # Pod Manager API
- manager-rbac.yaml # Service account & 권한
- namespace.yaml # 네임스페이스 정의
- network-policies.yaml # 네트워크 격리
- traefik-middleware.yaml # HTTPS 리다이렉트
- turn-rest-proxy.yaml # TURN 서비스 프록시
- workspace-ingressroute.yaml # Workspace 라우팅 베이스
# TerraformLearn/terraform/ (인프라)
리소스:
- eks.tf # EKS 클러스터 설정
- karpenter.tf # 노드 자동 스케일링
- traefik.tf # Ingress 컨트롤러
- cloudflare-dns.tf # DNS 설정
- providers.tf # Terraform providers
# Selkies/k8s-*.yaml (WebRTC 인프라)
리소스:
- k8s-game-container.yaml # 게임 컨테이너 배포
- k8s-coturn.yaml # TURN 서버
- k8s-tun-rest.yaml # TURN REST API
- k8s-config.yaml # 설정
# k8s-setup-script/ (유틸리티 매니페스트)
리소스:
- dashboard/ # K8s 대시보드 설정
- NFS_mount_test/ # NFS 스토리지 테스트
- nginx-deploy.yaml # 샘플 nginx 배포
- busybox-pod.yaml # 디버그 pod4.3 배포 아키텍처
flowchart TB subgraph Prod["프로덕션 환경 (AWS EKS)"] subgraph TraefikNS["네임스페이스: traefik"] TraefikCtrl["Traefik Ingress Controller"] CertManager["cert-manager<br/>Let's Encrypt"] Wildcard["Wildcard Cert<br/>*.ccgp.dev"] end subgraph PodNS["네임스페이스: pod-manager"] PodManagerAPI["Pod-Manager<br/>API"] UserPods["사용자 Pods<br/>동적"] TurnServer["TURN Server<br/>coturn"] end subgraph PortalNS["네임스페이스: portal (암시적)"] PortalBackend["Portal Backend"] Celery["Celery Worker<br/>Celery Beat"] Redis["Redis<br/>캐시"] end subgraph NodePools["노드 풀 (Karpenter)"] CPUPool["CPU Pool<br/>t3.small / t3.medium<br/>Spot"] GPUPool["GPU Pool<br/>g4dn.xlarge<br/>NVIDIA T4<br/>Spot / On-Demand"] end end CertManager --> Wildcard TraefikCtrl --> PodManagerAPI TraefikCtrl --> PortalBackend PodManagerAPI --> UserPods TurnServer --> UserPods PortalBackend --> Celery PortalBackend --> Redis PortalBackend --> CPUPool PodManagerAPI --> GPUPool UserPods --> GPUPool
5. 공통 인프라
5.1 공통 Kubernetes 리소스
| 리소스 | 목적 | 위치 |
|---|---|---|
| Traefik IngressRoute CRD | HTTP 라우팅 | TerraformLearn/terraform/traefik.tf |
| Cert-Manager | SSL 인증서 관리 | TerraformLearn/terraform/traefik.tf |
| Karpenter NodePools | 자동 스케일링 | TerraformLearn/terraform/karpenter.tf |
| Wildcard Certificate | SSL for *.ccgp.dev | TerraformLearn/terraform/traefik.tf |
| Service Accounts | K8s RBAC | PodManager_V2/k8s/manager-rbac.yaml |
5.2 공유 설정
# 서비스 간 공통 환경 변수
# PodManager_V2
WORKSPACE_DOMAIN: "workspace.ccgp.dev"
USER_APP_IMAGE: "ccgp.dev/user-app:latest"
K8S_NAMESPACE: "pod-manager"
SESSION_COOKIE_NAME: "user-session-id"
USE_HTTPS: "true"
# game-container
SELKIES_ENCODER: "nvh264enc"
SELKIES_VIDEO_BITRATE: "8000"
SELKIES_FRAMERATE: "60"
SELKIES_TURN_REST_URI: "http://turn-rest:8008"
NVIDIA_DRIVER_CAPABILITIES: "all"
# portal-backend
APP_HOST: "${APP_HOST}"
APP_PORT: "${APP_PORT}"
POD_CONTROLLER_SERVICE: "pod-manager-service.pod-manager"5.3 네트워크 아키텍처
flowchart TB Internet["인터넷"] NLB["AWS NLB"] Traefik["Traefik<br/>Port 80 / 443"] PortalHost["portal.ccgp.dev"] WorkspaceHost["workspace.ccgp.dev"] Wildcard["*.ccgp.dev"] PortalService["Portal Backend Service"] CookieRoute["Dynamic Route<br/>Cookie match"] Default404["Default 404"] UserPod["사용자 Pod<br/>Selkies"] Policy["NetworkPolicy<br/>user-isolation-{session_id}<br/>Traefik 인바운드만 허용<br/>TURN REST 아웃바운드 허용"] Internet --> NLB --> Traefik Traefik --> PortalHost --> PortalService Traefik --> WorkspaceHost --> CookieRoute --> UserPod Traefik --> Wildcard --> Default404 Policy -.-> UserPod
6. 아키텍처 다이어그램
6.1 고수준 시스템 아키텍처
flowchart TB subgraph Client["클라이언트 계층"] Web["웹 Browser"] Mobile["모바일<br/>미래"] SteamClient["Steam 클라이언트<br/>WebRTC 통해"] end subgraph Ingress["Ingress 계층"] NLB["AWS Network Load Balancer<br/>고정 IP / EIP<br/>Traefik에서 TLS 종료"] Traefik["Traefik Ingress Controller<br/>IngressRoute CRDs<br/>HTTPS 리다이렉트 / BasicAuth<br/>쿠키 기반 라우팅"] end subgraph App["애플리케이션 계층"] UI["CCGP-ui<br/>React<br/>사용자 인증 / Workspace 관리 / 게임 실행"] Portal["portal-backend<br/>FastAPI<br/>Auth API / 과금 / 임대 / Workspace 프록시"] PodMgr["PodManager_V2<br/>FastAPI<br/>Pod 수명주기 / K8s API / 라우팅"] Celery["Celery Worker / Beat"] Flower["Flower<br/>모니터링"] end subgraph Data["데이터 계층"] PG["PostgreSQL<br/>주 DB"] Redis["Redis<br/>캐시 / 큐"] S3["S3<br/>암시적 스토리지"] end subgraph Container["컨테이너 계층"] Workspace["사용자 Workspace Pods<br/>game-container<br/>Ubuntu Desktop / Steam / Selkies / NVIDIA GPU"] Coturn["Coturn<br/>TURN 서버"] TurnRest["TURN REST<br/>Auth API"] Future["미래 서비스"] end subgraph Infra["인프라 계층"] EKS["AWS EKS<br/>Kubernetes"] Karpenter["Karpenter<br/>Auto-scale"] GPU["NVIDIA GPU Operator"] CPUNode["CPU 노드<br/>t3.small"] GPUNode["GPU 노드<br/>g4dn.xlarge"] Spot["Spot 인스턴스<br/>비용 최적화"] end Web --> NLB Mobile --> NLB SteamClient --> NLB NLB --> Traefik Traefik --> UI Traefik --> Portal Portal --> PodMgr Portal --> PG Portal --> Redis Portal --> Celery Celery --> Flower S3 -.-> Portal PodMgr --> Workspace Workspace --> Coturn Coturn --> TurnRest Future -.-> Workspace PodMgr --> EKS EKS --> Karpenter EKS --> GPU EKS --> CPUNode EKS --> GPUNode EKS --> Spot
6.2 Pod 수명주기 상태 머신
stateDiagram-v2 [*] --> IDLE state "IDLE\n활성 Workspace 없음" as IDLE state "CREATING" as CREATING state "PENDING\nGPU 노드 대기 중" as PENDING state "RUNNING\nPod 예약됨, Steam 준비" as RUNNING state "ACTIVE STREAMING\nWebRTC 스트리밍" as ACTIVE_STREAMING state "EXPIRED\ntimeout" as EXPIRED state "DELETED\n사용자 action" as DELETED state "STOPPED\n수동" as STOPPED IDLE --> CREATING: 사용자가 "Create Workspace" 클릭 CREATING --> PENDING CREATING --> RUNNING PENDING --> RUNNING: 노드 프로비저닝됨 RUNNING --> ACTIVE_STREAMING: 사용자가 Workspace 접근 ACTIVE_STREAMING --> EXPIRED ACTIVE_STREAMING --> DELETED ACTIVE_STREAMING --> STOPPED
6.3 요청 라우팅 흐름
flowchart TB subgraph Scenario1["시나리오 1: 포털 접근 (portal.ccgp.dev)"] S1A["사용자"] S1B["DNS<br/>Cloudflare"] S1C["AWS NLB"] S1D["Traefik"] S1E["포털 서비스"] S1F["Portal Backend API"] S1A --> S1B --> S1C --> S1D --> S1E --> S1F end subgraph Scenario2["시나리오 2: Workspace 접근 (workspace.ccgp.dev)"] S2A["사용자"] S2B["DNS"] S2C["AWS NLB"] S2D["Traefik"] S2E["IngressRoute 조회"] S2F["쿠키 user-session-id 일치"] S2G["user-service-{sid}로 라우팅"] S2H["사용자 Pod<br/>Selkies WebRTC"] S2A --> S2B --> S2C --> S2D --> S2E --> S2F --> S2G --> S2H end subgraph Scenario3["시나리오 3: API 접근 (api.ccgp.dev)"] S3A["클라이언트"] S3B["DNS"] S3C["AWS NLB"] S3D["Traefik"] S3E["Portal Backend API"] S3A --> S3B --> S3C --> S3D --> S3E end subgraph Rules["라우팅 규칙 요약"] R1["Host: workspace.ccgp.dev<br/>Cookie: user-session-id={uuid}<br/>-> user-service-{uuid}.pod-manager.svc.cluster.local"] R2["Host: portal.ccgp.dev<br/>Path: /api/*<br/>-> portal-service.portal.svc.cluster.local"] R3["Host: traefik.ccgp.dev<br/>-> Traefik Dashboard<br/>BasicAuth 포함"] end
7. 주요 통합 지점
7.1 핵심 API 계약
portal-backend ↔ PodManager_V2
# Request: Create Pod
POST /api/v1/pods
{
"username": "user-id",
"session_id": "uuid-v4",
"image": "ccgp.dev/user-app:latest",
"resources": {
"cpu_cores": 4,
"memory_gb": 8,
"gpu_count": 1
}
}
# Response
{
"session_id": "uuid-v4",
"username": "user-id",
"status": "Creating",
"created_at": "2026-03-23T10:00:00Z",
"workspace_url": "https://workspace.ccgp.dev"
}portal-backend → User (Cookie)
Set-Cookie: user-session-id={session_id};
Domain=.ccgp.dev;
Path=/;
Expires={30 days};
Secure;
HttpOnly;
SameSite=NoneTraefik → User Pod (IngressRoute)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: user-route-{session_id}
namespace: pod-manager
spec:
entryPoints:
- websecure
routes:
- match: >
Host(`workspace.ccgp.dev`) &&
HeaderRegexp(`Cookie`, `.*user-session-id={session_id}.*`)
kind: Rule
services:
- name: user-service-{session_id}
port: 8080
tls:
secretName: wildcard-ccgp-dev-tls7.2 데이터베이스 스키마 (추론)
erDiagram USERS { int id PK string email decimal balance boolean is_active boolean is_superuser } CONTAINER_RESOURCES { int idx PK uuid id string name string image json resource decimal price_per_min boolean is_active } CONTAINER_RENTALS { int idx PK uuid id int user_id FK int resource_idx FK string resource_name datetime start_time datetime endtime boolean is_active } TRANSACTIONS { int id PK int user_id FK decimal amount string type datetime created_at } USERS ||--o{ CONTAINER_RENTALS : rents CONTAINER_RESOURCES ||--o{ CONTAINER_RENTALS : selected_by USERS ||--o{ TRANSACTIONS : records
7.3 설정 매핑
| 컴포넌트 | 설정 소스 | 주요 변수 |
|---|---|---|
| portal-backend | .env 파일 | WRITER_DB_URL, REDIS_URL, POD_CONTROLLER_SERVICE |
| CCGP-ui | 환경 | VITE_API_URL |
| PodManager_V2 | 환경 | WORKSPACE_DOMAIN, USER_APP_IMAGE, K8S_NAMESPACE |
| game-container | 환경 | SELKIES_*, PASSWD, NVIDIA_* |
| Terraform | terraform.tfvars | cluster_name, aws_region, cloudflare_api_token |
8. 권장사항
8.1 아키텍처 개선사항
-
API Gateway 계층
- Kong 또는 AWS API Gateway를 추가하여 통합 API 관리 고려
- 속도 제한, 인증, 로깅 중앙화
-
모니터링 및 가시성
- Prometheus + Grafana를 추가하여 메트릭 수집
- 분산 추적 구현 (Jaeger/Zipkin)
- 모든 서비스에 상태 확인 추가
-
보안 강화
- 서비스 간 상호 TLS 구현
- Pod Security Policies 추가 (또는 K8s 1.25+용 Pod Security Standards)
- 컨테이너 이미지의 정기적인 보안 스캔
-
비용 최적화
- 더 공격적인 Karpenter 통합 정책 구현
- 비피크 시간대의 예약된 스케일링 추가
- Spot 인스턴스 중단 처리 고려
8.2 코드 조직
-
저장소 통합
- PodManager와 PodManager_V2 병합 고려 (v2만 유지)
- 데모 설정을 메인 배포 저장소로 병합
-
공유 라이브러리
- 공통 K8s 유틸리티를 공유 라이브러리로 추출
- 공통 베이스 Docker 이미지 생성
-
문서화
- 아키텍처 결정 레코드 (ADRs) 추가
- OpenAPI 사양으로 API 계약 문서화
8.3 배포 개선사항
-
GitOps 워크플로우
- ArgoCD 또는 Flux를 사용한 GitOps 배포 구현
- 인프라와 애플리케이션 관심사 분리
-
환경 관리
- 스테이징 환경 추가
- 점진적 롤아웃을 위한 기능 플래그 구현
-
백업 및 DR
- 데이터베이스 백업 전략 구현
- 재해 복구 절차 문서화
Appendix A: 저장소 파일 구조
CCG-Platform/
├── CCG-Platform/ # 메인 조직 저장소 (최소)
│ └── README.md
│
├── portal-backend/ # 메인 백엔드 API
│ ├── src/
│ │ ├── application/api/v1/ # API 라우트
│ │ ├── infrastructure/ # DB, Redis, Celery
│ │ └── core/ # 설정, 로깅
│ ├── docker-compose.yml # 로컬 개발
│ └── Dockerfile
│
├── CCGP-ui/ # 프론트엔드 React 앱
│ ├── src/
│ │ ├── components/ # React 컴포넌트
│ │ └── page/ # 페이지 컴포넌트
│ ├── docker-compose.yml
│ └── Dockerfile
│
├── PodManager/ # K8s pod manager v1 (레거시)
│ ├── docker/ # Docker 배포
│ ├── k8s/ # K8s 매니페스트
│ └── production*/ # 프로덕션 변형
│
├── PodManager_V2/ # K8s pod manager v2 (프로덕션)
│ ├── manager/ # Manager API
│ │ ├── src/pod_manager/
│ │ └── templates/ # K8s 리소스 템플릿
│ ├── user-app/ # 사용자 workspace 베이스 이미지
│ └── k8s/ # K8s 배포 매니페스트
│
├── game-container/ # Steam 게임 컨테이너
│ ├── Dockerfile # selkies-nvidia-egl 기반
│ └── docker-compose.yml # 로컬 테스트
│
├── Selkies/ # WebRTC 스트리밍 컴포넌트
│ └── k8s-*.yaml # K8s 매니페스트
│
├── TerraformLearn/ # Infrastructure as Code
│ └── terraform/
│ ├── eks.tf # EKS 클러스터
│ ├── karpenter.tf # 자동 스케일링
│ ├── traefik.tf # Ingress 컨트롤러
│ └── *.tf # 기타 리소스
│
├── k8s-setup-script/ # K8s 유틸리티 스크립트
│ ├── dashboard/ # K8s 대시보드 설정
│ └── NFS_mount_test/ # 스토리지 테스트
│
├── POC/ # 개념 증명
│ └── docker-compose.yaml # SteamOS POC
│
├── demo/ # 데모 배포
│ └── portal-deployment.yaml # 포털 데모
│
└── Document/ # 문서
└── (Markdown 문서)
Appendix B: 기술 스택 요약
| 계층 | 기술 | 버전 | 목적 |
|---|---|---|---|
| 프론트엔드 | React | 18+ | UI 프레임워크 |
| 프론트엔드 | Vite | Latest | 빌드 도구 |
| 백엔드 | Python | 3.11+ | 런타임 |
| 백엔드 | FastAPI | Latest | API 프레임워크 |
| 백엔드 | Celery | Latest | 태스크 큐 |
| 백엔드 | SQLAlchemy | 2.0+ | ORM |
| 데이터베이스 | PostgreSQL | 15+ | 주 DB |
| 캐시 | Redis | 6.2+ | 캐시/큐 |
| 컨테이너 | Docker | Latest | 컨테이너화 |
| 오케스트레이션 | Kubernetes | 1.33 | 컨테이너 오케스트레이션 |
| 클라우드 | AWS EKS | Latest | 관리형 K8s |
| 자동 스케일링 | Karpenter | Latest | 노드 프로비저닝 |
| Ingress | Traefik | v3.0 | 리버스 프록시 |
| SSL | cert-manager | Latest | 인증서 관리 |
| DNS | Cloudflare | - | DNS & CDN |
| GPU | NVIDIA GPU Operator | v25.3.2 | GPU 관리 |
| 스트리밍 | Selkies-GStreamer | Latest | WebRTC 스트리밍 |
| TURN | Coturn | Latest | WebRTC 릴레이 |
| IaC | Terraform | 1.0+ | 인프라 |
| 스트리밍 | WebRTC | - | 실시간 스트리밍 |
Cross-Repository 분석 문서의 끝