# Forge Server — James's Future Home *Last updated: 2026-02-04* **This IS my primary home.** Migration completed 2026-02-04. IP swapped to 192.168.1.16. --- ## Hardware | Component | Details | |-----------|---------| | **Machine** | Lenovo ThinkServer TS140 (second unit) | | **CPU** | Intel Core i7-6700K @ 4.0GHz (4c/8t, HyperThreading) | | **RAM** | 64GB DDR4 | | **GPU** | NVIDIA GeForce GTX 970 4GB (compute 5.2, Maxwell) | | **Storage** | 469GB NVMe (28G used, 417G free = 7%) | | **Network** | Single NIC, enp10s0, 192.168.3.138/22 | ## OS & Kernel - **OS:** Ubuntu 24.04.3 LTS (Server, headless) - **Kernel:** 6.8.0-94-generic - **Timezone:** America/New_York ## Network - **IP:** 192.168.1.16 (swapped from old james on 2026-02-04) - **Subnet:** 192.168.0.0/22 - **Gateway:** (standard home network) - **DNS:** systemd-resolved (127.0.0.53, 127.0.0.54) ## Access - **SSH:** Key auth only (password auth disabled, root login disabled) - **Authorized keys:** - `james@server` — James (primary) - `johan@ubuntu2404` — Johan - `claude@macbook` — Johan's Mac - **Sudo:** Passwordless (`johan ALL=(ALL) NOPASSWD:ALL`) - **Linger:** Enabled (user services persist without active SSH) ## Security - **Firewall (UFW):** Active - Rule 1: SSH (22/tcp) from anywhere - Rule 2: All traffic from LAN (192.168.0.0/22) - Default: deny incoming, allow outgoing - **Fail2ban:** Active, monitoring sshd - **Unattended upgrades:** Enabled - **Sysctl hardening:** rp_filter, syncookies enabled - **Disabled services:** snapd, ModemManager - **Still enabled (fix later):** cloud-init ## GPU Stack - **Driver:** nvidia-headless-580 + nvidia-utils-580 (v580.126.09) - **CUDA:** 13.0 (reported by nvidia-smi) - **Persistence mode:** Enabled - **VRAM:** 4096 MiB total, ~2.2 GB used by OCR model - **Temp:** ~44-51°C idle - **CRITICAL:** GTX 970 = compute capability 5.2 (Maxwell) - PyTorch ≤ 2.2.x only (newer drops sm_52 support) - Must use CUDA 11.8 wheels ## Python Environment - **Path:** `/home/johan/ocr-env/` - **Python:** 3.12.3 - **Key packages:** - PyTorch 2.2.2+cu118 - torchvision 0.17.2+cu118 - transformers 5.0.1.dev0 (installed from git, has GLM-OCR support) - accelerate 1.12.0 - FastAPI 0.128.0 - uvicorn 0.40.0 - Pillow (for image processing) - **Monkey-patch:** `transformers/utils/generic.py` patched for `torch.is_autocast_enabled()` compat with PyTorch 2.2 ## Services ### OCR Service (GLM-OCR) - **Port:** 8090 (0.0.0.0) - **Service:** `systemctl --user status ocr-service` - **Unit file:** `~/.config/systemd/user/ocr-service.service` - **Source:** `/home/johan/ocr-service/server.py` - **Model:** `/home/johan/models/glm-ocr` (zai-org/GLM-OCR, 2.47 GB) **Endpoints:** - `GET /health` — status, GPU memory, model info - `POST /ocr` — single image (multipart: file + prompt + max_tokens) - `POST /ocr/batch` — multiple images **Performance:** - Model load: ~1.4s (stays warm in VRAM) - Small images: ~2s - Full-page documents: ~25s (auto-resized to 1280px max) - VRAM: 2.2 GB idle, peaks ~2.8 GB during inference **Usage from james:** ```bash # Health check curl http://192.168.3.138:8090/health # OCR a single image curl -X POST http://192.168.3.138:8090/ocr -F "file=@image.png" # OCR with custom prompt curl -X POST http://192.168.3.138:8090/ocr -F "file=@doc.png" -F "prompt=Extract all text:" ``` ### Ollama - **Port:** 11434 (localhost only) - **Version:** 0.15.4 - **Status:** Installed, waiting for v0.15.5 for native GLM-OCR support - **Note:** Not currently used — Python/transformers handles OCR directly ## Migration Plan: james → forge ### What moves: - [ ] OpenClaw gateway (port 18789) - [ ] Signal-cli daemon (port 8080) - [ ] Proton Mail Bridge (ports 1143, 1025) - [ ] Mail Bridge / Message Center (port 8025) - [ ] Message Bridge / WhatsApp (port 8030) - [ ] Dashboard (port 9200) - [ ] Headless Chrome (port 9223) - [ ] All workspace files (`~/clawd/`) - [ ] Document management system - [ ] Cron jobs and heartbeat config - [ ] SSH keys and configs ### What stays on james (or TBD): - Legacy configs / backups - SMB shares (maybe move too?) ### Pre-migration checklist: - [ ] Install Node.js 22 on forge - [ ] Install OpenClaw on forge - [ ] Set up Signal-cli on forge - [ ] Set up Proton Mail Bridge on forge - [ ] Set up message-bridge (WhatsApp) on forge - [ ] Set up headless Chrome on forge - [ ] Copy workspace (`~/clawd/`) to forge - [ ] Copy documents system to forge - [ ] Test all services on forge before switchover - [ ] Update DNS/Caddy to point to forge IP - [ ] Update TOOLS.md, MEMORY.md with new IPs - [ ] Verify GPU OCR still works alongside gateway ### Advantages of forge over james: - **CPU:** i7-6700K (4c/8t, 4.0GHz) vs Xeon E3-1225v3 (4c/4t, 3.2GHz) — faster + HT - **RAM:** 64GB vs 16GB — massive headroom - **GPU:** GTX 970 for local ML inference - **Storage:** 469GB NVMe vs 916GB SSD — less space but faster - **Network:** Same /22 subnet, same LAN access to everything ### Risks: - Storage is smaller (469G vs 916G) — may need to be selective about what moves - GPU driver + gateway on same box — monitor for resource conflicts - Signal-cli needs to re-link or transfer DB - WhatsApp bridge needs QR re-link --- ## Directory Layout ``` /home/johan/ ├── ocr-env/ # Python venv (PyTorch + transformers) ├── ocr-service/ # FastAPI OCR server │ └── server.py ├── models/ │ └── glm-ocr/ # GLM-OCR weights (2.47 GB) ├── .config/ │ └── systemd/user/ │ └── ocr-service.service └── .ssh/ └── authorized_keys ``` ## Key Constraints 1. **PyTorch version locked to 2.2.x** — GTX 970 sm_52 not supported in newer 2. **CUDA 11.8 wheels only** — matches PyTorch 2.2 requirement 3. **Max image dimension 1280px** — larger causes excessive VRAM/time on GTX 970 4. **transformers from git** — stock pip version doesn't have GLM-OCR model class 5. **Monkey-patch required** — `torch.is_autocast_enabled()` API changed in PyTorch 2.4