headscale-tailscale-replace.../PROXMOX_VNC_INTEGRATION_PLAN.md
시골약사 35ecd4748e PharmQ SaaS 구독 서비스 관리 시스템 완전 구현
📋 기획 및 설계:
- PharmQ SaaS 서비스 기획서 작성
- 구독 서비스 라인업 정의 (클라우드PC, AI CCTV, CRM)
- DB 스키마 설계 및 API 아키텍처 설계

🗄️ 데이터베이스 구조:
- service_products: 서비스 상품 마스터 테이블
- pharmacy_subscriptions: 약국별 구독 현황 테이블
- subscription_usage_logs: 서비스 이용 로그 테이블
- billing_history: 결제 이력 테이블
- 샘플 데이터 자동 생성 (21개 구독, 월 118만원 매출)

🔧 백엔드 API 구현:
- 구독 현황 통계 API (/api/subscriptions/stats)
- 약국별 구독 조회 API (/api/pharmacies/subscriptions)
- 구독 상세 정보 API (/api/pharmacy/{id}/subscriptions)
- 구독 생성/해지 API (/api/subscriptions)

🖥️ 프론트엔드 UI 구현:
- 대시보드 구독 현황 카드 (월 매출, 구독 수, 구독률 등)
- 약국 목록에 구독 상태 아이콘 및 월 구독료 표시
- 약국 상세 페이지 구독 서비스 섹션 추가
- 실시간 구독 생성/해지 기능 구현

 주요 특징:
- 서비스별 색상 코딩 및 이모지 아이콘 시스템
- 실시간 업데이트 (구독 생성/해지 즉시 반영)
- 반응형 디자인 (모바일/태블릿 최적화)
- 툴팁 기반 상세 정보 표시

📊 현재 구독 현황:
- 총 월 매출: ₩1,180,000
- 구독 약국: 10/14개 (71.4%)
- AI CCTV: 6개 약국, CRM: 10개 약국, 클라우드PC: 5개 약국

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 19:48:12 +09:00

376 lines
12 KiB
Markdown

# 팜큐(FARMQ) Proxmox VNC 통합 시스템 기획서
## 🎯 프로젝트 개요
### 목표
Flask Admin 웹 인터페이스에서 **한 번의 클릭**으로 Proxmox VM의 VNC 화면에 접속할 수 있는 통합 시스템 구축
### 핵심 아이디어
1. **Headscale 네트워크**를 통해 모든 약국의 Proxmox 호스트에 접근 가능
2. **Proxmox VNC API**를 활용하여 VM 화면 원격 제어
3. **브라우저 기반 VNC 클라이언트** (Guacamole/noVNC)로 즉시 접속
4. **Flask Admin 버튼****VNC 화면** 원클릭 연결
## 🏗️ 시스템 아키텍처
```
[Flask Admin Dashboard]
↓ (클릭)
[VNC 연결 요청 API]
[Headscale 네트워크]
↓ (100.64.0.x)
[Proxmox Host Server]
↓ (VNC API)
[VM VNC Console]
[noVNC/Guacamole Web Client]
[사용자 브라우저]
```
## 📋 기술 스택
### Frontend
- **noVNC**: HTML5 VNC 클라이언트 (가벼움, 쉬운 통합)
- **Apache Guacamole**: 더 고급 기능 (클립보드, 파일 전송)
- **Bootstrap 5**: UI 프레임워크
### Backend
- **Flask**: 웹 서버 및 API
- **Proxmox VE API**: VM 관리 및 VNC 토큰 생성
- **WebSocket Proxy**: VNC 트래픽 중계
### Network
- **Headscale**: 팜큐 네트워크 (100.64.0.0/10)
- **Tailscale**: 각 Proxmox 호스트 연결
## 🔧 구현 단계
### Phase 1: Proxmox API 통합 (1-2일)
#### 1.1 Proxmox API 클라이언트 구현
```python
# utils/proxmox_client.py
class ProxmoxClient:
def __init__(self, host, username, password):
self.host = host # 100.64.0.x (Headscale IP)
def get_vm_list(self):
"""VM 목록 조회"""
def get_vnc_ticket(self, vmid):
"""VNC 접속 티켓 생성"""
def get_vm_status(self, vmid):
"""VM 상태 확인"""
```
#### 1.2 데이터베이스 모델 확장
```python
# models/farmq_models.py
class ProxmoxVM(FarmqBase):
__tablename__ = 'proxmox_vms'
id = Column(Integer, primary_key=True)
pharmacy_id = Column(Integer, ForeignKey('pharmacy_info.id'))
proxmox_host_ip = Column(String(15)) # 100.64.0.x
vmid = Column(Integer)
vm_name = Column(String(100))
vm_type = Column(String(50)) # windows, linux
status = Column(String(20)) # running, stopped
cpu_cores = Column(Integer)
memory_mb = Column(Integer)
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
```
### Phase 2: VNC 웹 클라이언트 구현 (2-3일)
#### 2.1 noVNC 통합 (권장)
```html
<!-- templates/vnc/novnc.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ vm_name }} - VNC Console</title>
<script src="/static/novnc/vnc.js"></script>
</head>
<body>
<div id="vnc-container">
<canvas id="vnc-canvas"></canvas>
</div>
<script>
const rfb = new RFB(document.getElementById('vnc-canvas'),
'ws://{{ flask_server }}/vnc/{{ session_id }}');
</script>
</body>
</html>
```
#### 2.2 WebSocket Proxy 서버
```python
# vnc_proxy.py
import websockets
import asyncio
class VNCProxy:
async def proxy_vnc_connection(self, websocket, path):
# Flask → Proxmox VNC 연결 중계
session_id = extract_session_id(path)
proxmox_vnc = await connect_to_proxmox_vnc(session_id)
# 양방향 데이터 중계
await asyncio.gather(
relay_websocket_to_vnc(websocket, proxmox_vnc),
relay_vnc_to_websocket(proxmox_vnc, websocket)
)
```
### Phase 3: Flask Admin 통합 (1일)
#### 3.1 VNC 연결 API 엔드포인트
```python
# app.py
@app.route('/api/vm/<int:vm_id>/vnc', methods=['POST'])
def connect_vm_vnc(vm_id):
"""VM VNC 연결 세션 생성"""
try:
vm = get_vm_by_id(vm_id)
proxmox = ProxmoxClient(vm.proxmox_host_ip, username, password)
# VNC 티켓 생성
vnc_ticket = proxmox.get_vnc_ticket(vm.vmid)
# 세션 생성
session_id = create_vnc_session(vm_id, vnc_ticket)
return jsonify({
'session_id': session_id,
'vnc_url': f'/vnc/console/{session_id}',
'vm_info': vm.to_dict()
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/vnc/console/<session_id>')
def vnc_console(session_id):
"""VNC 콘솔 페이지"""
session = get_vnc_session(session_id)
return render_template('vnc/novnc.html',
session=session,
vm_name=session['vm_name'])
```
#### 3.2 약국 관리 페이지 업데이트
```html
<!-- templates/pharmacy/detail.html -->
<div class="card">
<div class="card-header">
<h5>가상 머신 목록</h5>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th>VM 이름</th>
<th>상태</th>
<th>타입</th>
<th>리소스</th>
<th>액션</th>
</tr>
</thead>
<tbody>
{% for vm in pharmacy_vms %}
<tr>
<td>{{ vm.vm_name }}</td>
<td>
{% if vm.status == 'running' %}
<span class="badge bg-success">실행 중</span>
{% else %}
<span class="badge bg-secondary">정지</span>
{% endif %}
</td>
<td>{{ vm.vm_type }}</td>
<td>{{ vm.cpu_cores }}C / {{ vm.memory_mb }}MB</td>
<td>
{% if vm.status == 'running' %}
<button class="btn btn-primary btn-sm"
onclick="openVNC({{ vm.id }})">
<i class="fas fa-desktop"></i> VNC 접속
</button>
{% endif %}
<button class="btn btn-info btn-sm"
onclick="showVMDetails({{ vm.id }})">
<i class="fas fa-info-circle"></i> 상세
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<script>
async function openVNC(vmId) {
try {
showSpinner('VNC 연결 준비 중...');
const response = await fetch(`/api/vm/${vmId}/vnc`, {
method: 'POST'
});
const data = await response.json();
if (response.ok) {
// 새 탭에서 VNC 콘솔 열기
window.open(data.vnc_url, '_blank',
'width=1024,height=768,scrollbars=yes,resizable=yes');
} else {
showToast(data.error, 'error');
}
} catch (error) {
showToast('VNC 연결 실패: ' + error.message, 'error');
} finally {
hideSpinner();
}
}
</script>
```
## 📊 데이터 흐름
### 1. VM 목록 동기화
```
Proxmox API → Flask Backend → Database → Admin Dashboard
```
### 2. VNC 연결 프로세스
```
1. 사용자가 "VNC 접속" 버튼 클릭
2. Flask API가 Proxmox API 호출하여 VNC 티켓 생성
3. WebSocket 프록시 세션 생성
4. 새 브라우저 탭에서 noVNC 클라이언트 실행
5. 실시간 VM 화면 표시
```
## 🔐 보안 고려사항
### 인증 및 권한
```python
# 약국별 VM 접근 권한 검증
def check_vm_access_permission(user_id, vm_id):
"""사용자가 해당 VM에 접근 권한이 있는지 확인"""
user_pharmacy = get_user_pharmacy(user_id)
vm_pharmacy = get_vm_pharmacy(vm_id)
return user_pharmacy.id == vm_pharmacy.id
# VNC 세션 시간 제한
VNC_SESSION_TIMEOUT = 3600 # 1시간
```
### 네트워크 보안
- **Headscale 네트워크 내부**에서만 Proxmox 접근
- **HTTPS/WSS** 암호화 통신
- **세션 기반** 일회성 VNC 토큰
## 🎨 UI/UX 설계
### 메인 대시보드
```
┌─────────────────────────────────────────┐
│ 📊 팜큐 관리 대시보드 │
├─────────────────────────────────────────┤
│ 약국: 세종온누리약국 │
│ ┌─────────┬──────────┬────────┬─────────┐ │
│ │ VM 이름 │ 상태 │ 타입 │ 액션 │ │
│ ├─────────┼──────────┼────────┼─────────┤ │
│ │ POS-01 │ 🟢 실행중 │ Win11 │ [VNC접속]│ │
│ │ SERVER │ 🟢 실행중 │ Ubuntu │ [VNC접속]│ │
│ │ BACKUP │ ⚪ 정지 │ Win10 │ [시작] │ │
│ └─────────┴──────────┴────────┴─────────┘ │
└─────────────────────────────────────────┘
```
### VNC 콘솔 화면
```
┌─────────────────────────────────────────┐
│ 🖥️ POS-01 (Windows 11) - VNC Console │
├─────────────────────────────────────────┤
│ [전체화면] [클립보드] [Ctrl+Alt+Del] │
├─────────────────────────────────────────┤
│ │
│ VM 화면이 여기에 표시 │
│ (noVNC Canvas) │
│ │
└─────────────────────────────────────────┘
```
## 📋 구현 체크리스트
### Backend (Flask)
- [ ] Proxmox API 클라이언트 구현
- [ ] ProxmoxVM 데이터 모델 생성
- [ ] VNC 세션 관리 시스템
- [ ] WebSocket 프록시 서버
- [ ] API 엔드포인트 구현
### Frontend (Templates)
- [ ] noVNC 라이브러리 통합
- [ ] VNC 콘솔 페이지 템플릿
- [ ] 약국 상세 페이지 VM 섹션
- [ ] JavaScript VNC 연결 함수
### 시스템 통합
- [ ] VM 목록 자동 동기화
- [ ] 권한 검증 시스템
- [ ] 에러 처리 및 로깅
- [ ] 성능 최적화
## 🚀 배포 계획
### 개발 환경 테스트
1. **로컬 Proxmox 테스트**: VirtualBox/VMware로 Proxmox VE 설치
2. **noVNC 연동 테스트**: 기본 VNC 연결 확인
3. **Headscale 네트워크 테스트**: 원격 Proxmox 접근
### 운영 환경 적용
1. **점진적 배포**: 1개 약국부터 테스트
2. **모니터링 시스템**: VNC 연결 로그 및 성능 측정
3. **백업 접근 방법**: VNC 실패 시 SSH/RDP 대안
## 💡 추가 기능 아이디어
### Phase 2 고급 기능
- **다중 모니터 지원**: VM이 여러 화면을 사용하는 경우
- **클립보드 공유**: 로컬 PC ↔ 원격 VM 텍스트 복사
- **파일 전송**: 드래그앤드롭 파일 업로드
- **스크린샷 캡처**: 문제 해결을 위한 화면 저장
- **세션 녹화**: 작업 과정 기록
### 모니터링 및 분석
- **VNC 사용 통계**: 접속 시간, 빈도 분석
- **VM 성능 모니터링**: CPU, 메모리 사용률 실시간 표시
- **접속 이력 관리**: 언제, 누가, 어떤 VM에 접속했는지 로그
## 🎯 예상 효과
### 업무 효율성
- **즉시 원격 지원**: 약국 직원 도움 요청 시 바로 화면 접속
- **중앙 집중 관리**: 모든 약국 VM을 한 곳에서 관리
- **문제 해결 시간 단축**: 전화 설명 → 직접 화면 제어
### 기술적 장점
- **Headscale 네트워크 활용**: 기존 인프라 최대한 활용
- **브라우저 기반**: 별도 소프트웨어 설치 불필요
- **확장성**: 새로운 약국 추가 시 자동 연동
---
## 📞 문의 및 지원
이 시스템 구현 과정에서 기술적 이슈나 추가 요구사항이 있으면 언제든 문의하세요.
**핵심 목표**: 🖱️ **원클릭** → 🖥️ **VM 화면 접속**