Tổng quan kiến trúc
Tham khảo design choices từ kinh nghiệm thực tế setup AIWS production.
Tổng quan cài đặt
Phần tiêu đề “Tổng quan cài đặt”PC (always-on, LAN cáp) Laptop (mobile, wifi)┌─────────────────────────────────┐ ┌─────────────────────────────────┐│ Windows Syncthing :8384 │←──────→│ Windows Syncthing :8384 ││ ├─ claude-state │ TLS │ ├─ claude-state ││ │ → C:\Users\<u>\.claude\ │ P2P │ │ ││ └─ code-public-lan │ │ └─ code-public-lan ││ → D:\Public LAN Folder\ │ │ ││ │ │ ││ ┌─ WSL Ubuntu ──────────────┐ │ │ ┌─ WSL Ubuntu ──────────────┐ ││ │ WSL Syncthing :8385 │←─┼────────┼─→│ WSL Syncthing :8385 │ ││ │ (BEP 22001, mirrored mode) │ │ │ │ (BEP 22001) │ ││ │ │ │ │ │ │ ││ │ └─ wsl-projects │ │ │ │ └─ wsl-projects │ ││ │ → /home/<u>/projects/ │ │ │ │ → /home/<u>/projects/ │ ││ └────────────────────────────┘ │ │ └────────────────────────────┘ │└─────────────────────────────────┘ └─────────────────────────────────┘Design decisions:
Quyết định 1: 2 instance Syncthing mỗi máy (Windows + WSL)
Phần tiêu đề “Quyết định 1: 2 instance Syncthing mỗi máy (Windows + WSL)”Alternative không chọn: Single Windows Syncthing access cả Windows + WSL paths qua \\wsl.localhost\.
Rationale:
- 9P protocol read WSL files từ Windows = cực chậm (~33 MB/min vs native 3952 MB/min, 120x slower)
- WSL native paths = ext4 native speed
- Trade-off: 2 instances RAM ~200 MB vs gain 120x performance trên WSL folders
Cost: 2 Web UIs (port 8384 + 8385), 2 Device IDs per máy, 4 Device IDs total network.
Quyết định 2: Mirrored networking
Phần tiêu đề “Quyết định 2: Mirrored networking”Alternative không chọn: NAT’d default WSL networking + port forwarding.
Rationale với mirrored:
- WSL processes share host LAN IP — laptop’s WSL reach PC’s WSL trực tiếp
- No netsh portproxy maintenance
- WSL IP không thay đổi sau reboot (always = host IP)
- Better cho cross-WSL sync
Cost:
wsl --shutdown1 lần khi enable (n8n down 30-60s, auto-restart)- Một số apps có thể cần re-config nếu rely on NAT’d 172.x
Khi nào KHÔNG dùng mirrored: Win11 < 22H2, hoặc apps phụ thuộc NAT’d networking.
Quyết định 3: Phân bổ port 8384/22000 so với 8385/22001
Phần tiêu đề “Quyết định 3: Phân bổ port 8384/22000 so với 8385/22001”| Service | Windows | WSL |
|---|---|---|
| GUI Web UI | 8384 (default) | 8385 |
| BEP TCP+QUIC | 22000 (default) | 22001 |
| Local discovery | 21027 (default) | 21028 |
Rationale: với mirrored mode, WSL share host port space → conflict nếu cả 2 đều dùng 22000.
Why next sequential numbers (84→85, 22000→22001): dễ nhớ, no clash với well-known ports khác.
Quyết định 4: Đồng bộ cả ~/.claude/ hay từng subfolder
Phần tiêu đề “Quyết định 4: Đồng bộ cả ~/.claude/ hay từng subfolder”Sync whole (chosen):
- ✅ Single folder rule, ignore patterns đơn giản
- ✅
.credentials.jsonauto-sync (OAuth tokens) - ❌ Per-machine state (
session-env/,shell-snapshots/) phải ignore
Alternative — only projects/ + skills/:
- ✅ Cleaner separation
- ❌
.credentials.jsonoutside → manual handle separately - ❌ Settings, memory cần extra folders
→ Whole + ignore = pragmatic.
Quyết định 5: KHÔNG đồng bộ .claude.json (file đơn)
Phần tiêu đề “Quyết định 5: KHÔNG đồng bộ .claude.json (file đơn)”Why: Syncthing v2 không support sync single file. File .claude.json (~23KB) chứa mcpServers config + OAuth account info.
Workaround: copy manually qua shared folder khi update (rare event, vd add MCP).
Alternative: tạo wrapper folder + symlink (work nhưng more setup).
Quyết định 6: Ignore .git/objects/pack/ HAY KHÔNG?
Phần tiêu đề “Quyết định 6: Ignore .git/objects/pack/ HAY KHÔNG?”Sync .git/ whole (chosen):
- ✅ Preserve uncommitted local commits
- ❌ +5-10 GB storage cho large repos
Alternative — ignore .git/:
- ✅ Smaller sync footprint
- ❌ Mất uncommitted local commits → mỗi máy
git clonelại
→ Storage cheap, commits valuable. Sync whole.
Quyết định 7: n8n stack chỉ host trên PC
Phần tiêu đề “Quyết định 7: n8n stack chỉ host trên PC”Why:
- PC always-on có Cloudflare tunnel
n8n.aiws.vn - DB Postgres: file-level sync RISKY (binary, locked, corruption-prone)
- Single source of truth cho workflows + executions
- Laptop access via
n8n.aiws.vnURL → cùng instance
Cost: Khi PC tắt → laptop không access n8n. Mitigation: pg_dump weekly backup sync xuống laptop cho emergency restore.
Quyết định 8: Chấp nhận sync OAuth token
Phần tiêu đề “Quyết định 8: Chấp nhận sync OAuth token”Risk known: 1 máy refresh token → invalidate trên máy kia.
Why acceptable:
- User chỉ work 1 máy at a time → race condition rare
- Re-login ~30 giây nếu happen
- Convenience > 30s occasional re-login
KHÔNG acceptable case: 2 users share account đồng thời 2 máy → phải KHÔNG sync .credentials.json.
Luồng mạng
Phần tiêu đề “Luồng mạng”LAN scenario (cùng nhà)
Phần tiêu đề “LAN scenario (cùng nhà)”PC's Syncthing ↓ TLS 1.3 over TCP/QUIC ↓ Direct connection (no relay)Laptop's Syncthing
Path: PC IP (192.168.1.14) ↔ Laptop IP (192.168.1.16)Speed: LAN gigabit ~80-100 MB/s effectiveLatency: <1 msInternet scenario (đi xa)
Phần tiêu đề “Internet scenario (đi xa)”PC's Syncthing ↓ Connect to public Syncthing relay ↓ Relay forwards encrypted trafficLaptop's Syncthing (different LAN)
Path: PC → relay → Laptop (relay does not decrypt)Speed: Limited by upstream bandwidth + relay throughputLatency: 50-300 msBoth encrypted end-to-end. Relay servers cannot read content.
Luồng dữ liệu khi file thay đổi
Phần tiêu đề “Luồng dữ liệu khi file thay đổi”1. User edits file in synced folder (PC side)2. OS file watcher fires event (inotify/ReadDirectoryChangesW)3. Syncthing detects change → re-hash file blocks4. Syncthing publishes index update to peer (Laptop)5. Laptop compares index → detects new blocks6. Laptop requests blocks from PC7. PC sends blocks (encrypted)8. Laptop writes blocks to file9. Sync completeTotal time on LAN: <1s for small files, seconds for MB-sized.
Mô hình xử lý conflict
Phần tiêu đề “Mô hình xử lý conflict”Both peers offline → both edit same file → both come online ↓Syncthing detect: file modified time + content hash differ ↓Keep both versions: hello.txt ← latest from "winning" peer hello.sync-conflict-<date>-<peer>.txt ← other peer's version“Winning” peer = đang receive last (alphabetical Device ID tiebreaker).
User manually review + resolve.
Bước tiếp theo
Phần tiêu đề “Bước tiếp theo”- Future: VPS 3rd peer — extend architecture với cloud
- AI agent prompts — apply architecture