feat: home-gateway 초기 구성 — Mac mini에서 GPU 서버로 전면 이전

OrbStack 라이선스 만료로 Mac mini Docker 서비스를 GPU 서버로 통합.
nginx → Caddy 전환, 12개 서브도메인 자동 HTTPS, fail2ban Caddy JSON 연동.

주요 변경:
- home-caddy: Caddy 리버스 프록시 (Let's Encrypt 자동 HTTPS)
- home-fail2ban: Caddy JSON 로그 기반 보안 모니터링
- home-ddns: Cloudflare DDNS (API 키 .env 분리)
- gpu-hub-api/web: AI 백엔드 라우터 + 웹 UI (gpu-services에서 이전)
- AI 런타임(Ollama) 내부망 전용, 외부는 gpu-hub 인증 게이트웨이 경유

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-05 04:55:28 +00:00
commit 79c09cede4
52 changed files with 6847 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
from __future__ import annotations
import asyncio
import logging
from config import settings
logger = logging.getLogger(__name__)
async def get_gpu_info() -> dict | None:
"""Run nvidia-smi and parse GPU info."""
try:
proc = await asyncio.create_subprocess_exec(
settings.nvidia_smi_path,
"--query-gpu=utilization.gpu,temperature.gpu,memory.used,memory.total,power.draw,name",
"--format=csv,noheader,nounits",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=5.0)
if proc.returncode != 0:
logger.debug("nvidia-smi failed: %s", stderr.decode())
return None
line = stdout.decode().strip().split("\n")[0]
parts = [p.strip() for p in line.split(",")]
if len(parts) < 6:
return None
return {
"utilization": int(parts[0]),
"temperature": int(parts[1]),
"vram_used": int(parts[2]),
"vram_total": int(parts[3]),
"power_draw": float(parts[4]),
"name": parts[5],
}
except (FileNotFoundError, asyncio.TimeoutError):
return None