## 금도 서버 구성도

서버실 랙 사진과 현재 컨테이너/포트 운용 현황을 바탕으로 물리 배치와 논리 토폴로지를 정리했습니다. 운영 시 참조용으로 사용하며, 변경 시 본 문서도 함께 갱신합니다.

### 물리 랙 배치(위 → 아래)

아래는 랙 상의 장비 배치도입니다.

---
```mermaid
%%{init: {"theme": "base", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40, "useMaxWidth": false}, "themeVariables": { "fontSize": "20px", "lineHeight": "24px" }}}%%
graph TB
  subgraph "Rack Cabinet"
    direction TB
    R235["192.168.0.235 rack1 (R820)"]
    R236["192.168.0.236 rack2 (R820-2)"]
    MON["KVM/Monitor"]
    R102["192.168.0.102 nA100 (R760xa)"]
    R166["192.168.0.166 Sub AI (PT620)"]
    R029["192.168.0.29 Desktop"]
    R017["192.168.0.17 Synology NAS"]
    R066["192.168.0.66 GitLab & Nginx Proxy"]
  end

  R235 --> R236 --> MON --> R102 --> R166 --> R029 --> R017 --> R066

  style R102 fill:#e5f5ff,stroke:#1890ff,stroke-width:1.5px
  style R066 fill:#fff7e6,stroke:#fa8c16,stroke-width:1.5px
  style R017 fill:#f6ffed,stroke:#52c41a,stroke-width:1.5px
```

참고: 실제 장비 높이(U)와 정확한 선반 위치는 현장 라벨 기준으로 보정 가능합니다.

### 논리 네트워크/서비스 토폴로지

내부망 192.168.0.0/24 환경에서 리버스 프록시를 중심으로 주요 서비스가 분기됩니다.

---
```mermaid
%%{init: {"theme": "base", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40, "useMaxWidth": false}, "themeVariables": { "fontSize": "20px", "lineHeight": "24px" }}}%%
graph TB
  INET[인터넷]
  FW[게이트웨이/방화벽]
  PROXY["192.168.0.66 Nginx Proxy / GitLab"]

  INET --> FW --> PROXY

  subgraph Application_Servers
    direction TB
    A100["192.168.0.102 A100 (rvtouch3d, vnexa-abb, jupyter)"]
    RACK1["192.168.0.235 rack1 (3DP, vnexa-api, metaverse)"]
    RACK2["192.168.0.236 rack2 (java WAS)"]
    DESK["192.168.0.29 desktop (centos svc)"]
    SUBAI["192.168.0.166 sub ai (posivibes, db, gitlab_web)"]
    GDS["192.168.0.66 gds (fastapi, jupyter, webui, mail)"]
    A100 --> RACK1 --> RACK2 --> DESK --> SUBAI --> GDS
  end

  PROXY -->|HTTP/HTTPS 라우팅| A100
  PROXY --> RACK1
  PROXY --> RACK2
  PROXY --> DESK
  PROXY --> SUBAI
  PROXY --> GDS

  NAS["192.168.0.17 Synology NAS"]
  NAS -.-> A100
  NAS -.-> RACK1
  NAS -.-> RACK2
  NAS -.-> GDS
```
---

### 프록시 라우팅 맵(요약)

`@proxy_analysis.md`의 리버스 프록시 구성을 바탕으로, 주요 도메인 → 백엔드 목적지(내부 IP/포트)를 요약한 그래프입니다. 전체 목록은 `@proxy_analysis.md`의 표를 참고하세요.

```mermaid
%%{init: {"theme": "base", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40, "useMaxWidth": false}, "themeVariables": { "fontSize": "16px", "lineHeight": "22px" }}}%%
graph LR
  subgraph PROXY["Nginx Reverse Proxy (192.168.0.66)"]
    P[proxy.geumdo.net]
  end

  %% Sub AI (166)
  subgraph S166["192.168.0.166 Sub AI"]
    F0["fastapi.geumdo.net → 166:8000"]
    F1["fastapi-new.geumdo.net → 166:8001"]
    AIW["gdlab.co.kr → 166:4333 (HTTPS)"]
    UPG["dip-zero.geumdo.net → 166:4444 (HTTPS)"]
    UPH["max/geumdo/vnexa 계열 → 166:8093"]
    OLL["ollama.geumdo.net → 166:11434"]
  end

  %% GDS/서비스 허브 (70)
  subgraph S070["192.168.0.70 GDS/서비스 허브"]
    RVAPI["rvtouch3d-api.geumdo.net → 70:8001"]
    RVFE["rvtouch3d-test.geumdo.net → 70:3002"]
    JGPU["jupyter-gpu.geumdo.net → 70:8888 (WS)"]
    OUI["ollamaui.geumdo.net → 70:9000"]
  end

  %% Rack1 (235)
  subgraph S235["192.168.0.235 rack1"]
    G3DT["g3d-test.geumdo.net → 235:8090"]
    SW3D["sw3d-dev.geumdo.net → 235:8080"]
  end

  %% Rack2 (236)
  subgraph S236["192.168.0.236 rack2"]
    GBAX["gbmax.or.kr → 236:8092 (HTTPS)"]
    YNAX["max.or.kr → 236:8092 (HTTPS)"]
    FLK["flaskapi.geumdo.net → 236:3000"]
  end

  %% 기타 목적지
  subgraph ETC["기타 목적지"]
    IPT["setting.geumdo.net → 192.168.0.1:80 (ipTIME)"]
    NAS["nas.geumdo.net → 192.168.0.16:5000 (Synology)"]
    JNB["jupyter.geumdo.net → jupyter:8888 (WS)"]
  end

  %% Edges from Proxy
  P --> F0
  P --> F1
  P --> AIW
  P --> UPG
  P --> UPH
  P --> OLL

  P --> RVAPI
  P --> RVFE
  P --> JGPU
  P --> OUI

  P --> G3DT
  P --> SW3D

  P --> GBAX
  P --> YNAX
  P --> FLK

  P --> IPT
  P --> NAS
  P --> JNB

  %% Note
  NOTE["표에 없는 다수의 PHP-FPM, 레거시 서비스는 아래 PHP-FPM 맵과 proxy_analysis.md 전체 목록 참조"]
  P --- NOTE
```

---

### PHP-FPM 연동 맵(요약)

PHP-FPM 기반의 다수 사이트가 공존합니다. 버전별 소켓을 분리 운용합니다.

```mermaid
%%{init: {"theme": "base", "flowchart": {"nodeSpacing": 25, "rankSpacing": 35, "useMaxWidth": false}}}%%
graph TB
  subgraph PHP74["PHP 7.4-FPM (unix:/var/run/php/php7.4-fpm.sock)"]
    AIF[aifor.geumdo.net]
    ICT[ictcog.geumdo.net]
    DGEI[dgei.geumdo.net]
    SMS[sms.geumdo.net]
    PROJ[project.geumdo.net]
    RULLY[rully.geumdo.net]
    MORE74["... (다수) ..."]
  end

  subgraph PHP56["PHP 5.6-FPM (unix:/var/run/php/php5.6-fpm.sock)"]
    SW3D[sw3d.geumdo.net]
    G3DD[g3d-dev.geumdo.net]
    EVAL[eval.geumdo.net]
    LAC[lac.geumdo.net]
    VIS[visitor.geumdo.net]
    MORE56["... (다수) ..."]
  end

  classDef hint fill:#f6ffed,stroke:#52c41a,stroke-width:1px;
  HINT["세부 경로(root)와 도메인 전체 목록은 `@proxy_analysis.md` 표 참조"]:::hint
```

---

### SSL/TLS 적용 맵

인증서 관리 주체(수동/Certbot)와 기본 443 동작(일치 도메인 없음 시 444 반환)을 시각화했습니다.

```mermaid
%%{init: {"theme": "base", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40, "useMaxWidth": false}}}%%
graph LR
  subgraph CERTBOT["Certbot 자동 갱신"]
    PROXYD[proxy.geumdo.net]
    DIP[dip-zero.geumdo.net]
    MAIL[mail.geumdo.net]
  end

  subgraph MANUAL["수동 인증서 관리(/etc/nginx/ssl/…)"]
    GDL[gdlab.co.kr]
    GBMAX[gbmax.or.kr]
    GDN[geumdo.net / www.geumdo.net]
    MAX[max.or.kr]
  end

  subgraph DEFAULT443["기본 443 서버"]
    RET444["일치 도메인 없음 → 444 (연결 종료)"]
  end

  %% 서브그래프는 엣지 연결 대상이 될 수 없으므로, 각 노드 소속은 서브그래프로 표현하고 별도 엣지는 생략합니다.

  classDef info fill:#e6f7ff,stroke:#1890ff,stroke-width:1px;
  INFO["HTTP 요청은 대부분 HTTPS로 리다이렉트"]:::info
```

---

### 실시간 통신(WS/SSE) 라우팅

WebSocket 및 SSE 특수 처리를 요구하는 서비스 흐름을 분리하여 표시했습니다.

```mermaid
%%{init: {"theme": "base", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40, "useMaxWidth": false}}}%%
graph TB
  P66["Nginx Proxy (192.168.0.66)"]

  subgraph WS["WebSocket"]
    J1["jupyter.geumdo.net → :8888"]
    J2["jupyter-gpu.geumdo.net → 70:8888"]
    J3["jupyter-gpu2.geumdo.net → 71:8888"]
  end

  subgraph SSE["Server-Sent Events"]
    VX["vnexa-api.geumdo.net → 70:8000 (/api/v1/sse/) - proxy_buffering off; 타임아웃 확장"]
  end

  P66 --> J1
  P66 --> J2
  P66 --> J3
  P66 --> VX
```

---

### 장비 인벤토리

| IP | 호스트/별칭 | 하드웨어/호스트명 | 주요 컨테이너 및 포트(Host→Container) |
| :-- | :-- | :-- | :-- |
| 192.168.0.102 | A100 서버 | `gds-PowerEdge-R760xa` | vnexa-abb-api 8000→8000, rvtouch3d-api(frontend 3002→3000, grafana 3003→3000, app 8001→8000, prometheus 9092→9090, postgres 5434→5432, redis 6381→6379), jupyter-gpu 8888→8888 |
| 192.168.0.235 | geumdo rack1 | `gds-PowerEdge-R820` | 3DP 80/3000/3306/8080/8090/2212, vnexa-api 3001/2213, metaverse nodam 52530/52532-33/53306/2236 |
| 192.168.0.236 | geumdo rack2 | `gds-PowerEdge-R820-2` | java WAS 8092→8080, 4446→443, 33064→3306, 2233→22 |
| 192.168.0.29 | geumdo Desktop | `desktopserver` | docker_centos 8091→80, 4445→443, 33063→3306, 2230→22 |
| 192.168.0.166 | Sub AI 서버 | `gds-PT620` | posivibes 8084→8080, 2240→22; db 9011/9013/33062/2228; gitlab_web 8081→80, 4430→443, 2224→22; 기타(docker_all) |
| 192.168.0.66 | GitLab/Nginx/유틸 | `gds` | fastapi 8000→8000, fastapi_new 8001→8001, jupyter 8888→8888, open-webui 9000→8080, ollama 11434→11434, poste-io 메일 포트군, was/securedb 등 |
| 192.168.0.17 | Synology NAS | Synology | 파일공유/백업(스냅샷/rsync/HyperBackup) |

### Docker 공통 운용 메모

- 스토리지 드라이버: `overlay2`
- 기본 네트워크: `bridge`(172.17.0.0/16), `host`, `none`
- A100 서버는 프로젝트 분리를 위해 추가 브리지(`vnexa-abb-api_default`, 172.22.0.0/16) 사용
- 정기 점검: 외부 노출 포트 최소화, 불필요 컨테이너 정리, 이미지 업데이트

### 운영 체크리스트

- GitLab 접근 경로: 192.168.0.66(프록시) 및 192.168.0.166(컨테이너) 동시 운용 여부 확인
- NAS 백업: 각 서버의 애플리케이션 데이터/DB 스냅샷 주기 검토 및 복구 테스트
- 관리 인터페이스(iDRAC/IPMI) 주소 기록 및 비상접속 절차 정리
