feat: add VM sizing, host hardware specs and Proxmox provisioning steps
This commit is contained in:
174
README.md
174
README.md
@@ -150,6 +150,180 @@ Telegraf, Beszel
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Host Hardware
|
||||||
|
|
||||||
|
| Host | CPU | Logical CPUs | RAM | Storage | VM |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| dracula host | Xeon E5-1620 v2 @ 3.70GHz | 8 (4 cores + HT) | 64GB | Datacenter HDD | dracula-new (web) |
|
||||||
|
| transilvan host | Xeon E5-1620 v2 @ 3.70GHz | 8 (4 cores + HT) | 32GB | SSD | transilvan-new (db) |
|
||||||
|
|
||||||
|
Both hosts run Proxmox VE (confirmed via qemu-guest-agent on current VMs). New VMs are the sole tenants on their respective hosts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## VM Sizing
|
||||||
|
|
||||||
|
### Rationale for 200 concurrent users
|
||||||
|
|
||||||
|
With nginx fastcgi_cache, the vast majority of requests never invoke PHP. On a news site, traffic concentrates on recent articles — the hot working set is small and stays warm in FreeBSD's unified buffer cache (UBC) regardless of underlying disk speed.
|
||||||
|
|
||||||
|
| Metric | Value | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| Expected cache HIT rate | ~85–90% | News sites have concentrated traffic on recent content |
|
||||||
|
| Concurrent PHP requests at peak | ~20–30 | 200 users × ~15% miss rate |
|
||||||
|
| PHP-FPM workers (pm.max_children) | 40 | Headroom above expected peak |
|
||||||
|
| RAM per PHP-FPM worker | ~35MB RSS | WordPress with active plugins |
|
||||||
|
| PHP-FPM peak RAM | ~1.4GB | 40 workers × 35MB |
|
||||||
|
| nginx HIT response time | <5ms | Served from UBC, no PHP involved |
|
||||||
|
| nginx MISS response time | 100–400ms | WP query + render |
|
||||||
|
| InnoDB buffer pool hit rate | >99% | 20GB pool, 9.6GB dataset fits entirely in RAM |
|
||||||
|
| Active DB connections | ≤ 40 | One per active PHP-FPM worker |
|
||||||
|
|
||||||
|
### dracula-new (web VM on HDD host)
|
||||||
|
|
||||||
|
| Parameter | Value |
|
||||||
|
|---|---|
|
||||||
|
| vCPU | 6 |
|
||||||
|
| RAM | 14GB |
|
||||||
|
| Disk | 80GB single virtual disk (HDD-backed) |
|
||||||
|
| Balloon | Enabled (web VM, acceptable) |
|
||||||
|
|
||||||
|
RAM breakdown: PHP-FPM peak 1.4GB + Redis 512MB + nginx + UBC page cache for hot articles (~4–6GB effective) + OS 1GB + headroom.
|
||||||
|
|
||||||
|
HDD is acceptable for the web node. The fastcgi_cache working set for a news site fits in UBC (RAM). HDD latency only affects cold cache startup and log writes (sequential). The CPU and PHP-FPM worker slots are the actual bottleneck, not disk.
|
||||||
|
|
||||||
|
### transilvan-new (DB VM on SSD host)
|
||||||
|
|
||||||
|
| Parameter | Value |
|
||||||
|
|---|---|
|
||||||
|
| vCPU | 4 |
|
||||||
|
| RAM | 26GB |
|
||||||
|
| Disk 1 — OS | 40GB virtual (SSD-backed) |
|
||||||
|
| Disk 2 — ZFS data pool | 150GB virtual (SSD-backed) |
|
||||||
|
| Balloon | **Disabled** — memory ballooning must not reclaim InnoDB buffer pool RAM |
|
||||||
|
|
||||||
|
RAM breakdown: innodb_buffer_pool_size 20GB + MySQL overhead 2GB + OS 4GB.
|
||||||
|
|
||||||
|
Both virtual disks originate from the same physical SSD pool in Proxmox. Separation is logical: independent sizing, clean `zpool create data /dev/da1`, ZFS snapshots on the data disk without touching the OS disk, and easy future migration if a dedicated physical disk is added to the host.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## VM Provisioning (Proxmox)
|
||||||
|
|
||||||
|
### 1. Download FreeBSD 14.2 ISO on each Proxmox host
|
||||||
|
|
||||||
|
```sh
|
||||||
|
wget -P /var/lib/vz/template/iso/ \
|
||||||
|
https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/14.2/FreeBSD-14.2-RELEASE-amd64-disc1.iso
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create dracula-new (run on the HDD host)
|
||||||
|
|
||||||
|
Via CLI:
|
||||||
|
```sh
|
||||||
|
qm create 200 \
|
||||||
|
--name dracula-new \
|
||||||
|
--memory 14336 \
|
||||||
|
--balloon 14336 \
|
||||||
|
--cores 6 \
|
||||||
|
--cpu host \
|
||||||
|
--machine q35 \
|
||||||
|
--bios ovmf \
|
||||||
|
--efidisk0 local:1,format=raw \
|
||||||
|
--net0 virtio,bridge=vmbr0 \
|
||||||
|
--ostype other \
|
||||||
|
--scsihw virtio-scsi-single \
|
||||||
|
--scsi0 local:80,format=raw \
|
||||||
|
--cdrom local:iso/FreeBSD-14.2-RELEASE-amd64-disc1.iso \
|
||||||
|
--boot order=ide2;scsi0 \
|
||||||
|
--agent enabled=1
|
||||||
|
```
|
||||||
|
|
||||||
|
Via UI:
|
||||||
|
```
|
||||||
|
General → Name: dracula-new
|
||||||
|
OS → FreeBSD (other), ISO: FreeBSD-14.2-RELEASE-amd64-disc1.iso
|
||||||
|
System → Machine: q35, BIOS: OVMF (UEFI), Qemu Agent: ✓
|
||||||
|
Disks → VirtIO SCSI, 80GB, Cache: None
|
||||||
|
CPU → 6 cores, Type: host
|
||||||
|
Memory → 14336 MB
|
||||||
|
Network → VirtIO, vmbr0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Create transilvan-new (run on the SSD host)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# VM with OS disk
|
||||||
|
qm create 201 \
|
||||||
|
--name transilvan-new \
|
||||||
|
--memory 26624 \
|
||||||
|
--balloon 0 \
|
||||||
|
--cores 4 \
|
||||||
|
--cpu host \
|
||||||
|
--machine q35 \
|
||||||
|
--bios ovmf \
|
||||||
|
--efidisk0 local:1,format=raw \
|
||||||
|
--net0 virtio,bridge=vmbr0 \
|
||||||
|
--ostype other \
|
||||||
|
--scsihw virtio-scsi-single \
|
||||||
|
--scsi0 local:40,format=raw,discard=on,ssd=1 \
|
||||||
|
--cdrom local:iso/FreeBSD-14.2-RELEASE-amd64-disc1.iso \
|
||||||
|
--boot order=ide2;scsi0 \
|
||||||
|
--agent enabled=1
|
||||||
|
|
||||||
|
# Add second disk for ZFS data pool
|
||||||
|
qm set 201 --scsi1 local:150,format=raw,discard=on,ssd=1
|
||||||
|
```
|
||||||
|
|
||||||
|
`--balloon 0` disables memory ballooning on the DB VM. This is required — ballooning can silently reclaim pages from the InnoDB buffer pool under host memory pressure.
|
||||||
|
|
||||||
|
### 4. FreeBSD installer settings (same for both VMs)
|
||||||
|
|
||||||
|
```
|
||||||
|
Welcome screen → Install
|
||||||
|
Keymap → your preference
|
||||||
|
Hostname → dracula-new (or transilvan-new)
|
||||||
|
Distribution → base, kernel (nothing else)
|
||||||
|
Partitioning → Auto (ZFS)
|
||||||
|
Pool type → stripe (single disk)
|
||||||
|
Disk → da0 (the OS disk)
|
||||||
|
Swap → 2GB
|
||||||
|
Compress → lz4
|
||||||
|
Encrypt → No
|
||||||
|
Network → vtnet0, configure with a temporary IP for initial pkg bootstrap
|
||||||
|
(Tailscale will take over; this IP can be removed afterwards)
|
||||||
|
Mirror → closest region
|
||||||
|
Root password → set strong password
|
||||||
|
SSHD → enable
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. First boot — both VMs
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Update base system
|
||||||
|
freebsd-update fetch install
|
||||||
|
|
||||||
|
# Bootstrap pkg and install essentials
|
||||||
|
pkg update && pkg upgrade -y
|
||||||
|
pkg install -y qemu-guest-agent tailscale sudo curl wget
|
||||||
|
|
||||||
|
# Enable QEMU guest agent (so Proxmox can see VM IP, issue graceful shutdowns)
|
||||||
|
sysrc qemu_guest_agent_enable=YES
|
||||||
|
service qemu-guest-agent start
|
||||||
|
|
||||||
|
# Join Tailscale network
|
||||||
|
sysrc tailscaled_enable=YES
|
||||||
|
service tailscaled start
|
||||||
|
tailscale up --hostname=dracula-new # or transilvan-new
|
||||||
|
|
||||||
|
# Note the assigned Tailscale IP — plug into pf.conf and wp-config placeholders
|
||||||
|
tailscale ip -4
|
||||||
|
```
|
||||||
|
|
||||||
|
After both VMs have Tailscale IPs, replace all `<dracula-new Tailscale IP>` and `<transilvan-new Tailscale IP>` placeholders throughout this document and in all config files.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Migration Data Inventory
|
## Migration Data Inventory
|
||||||
|
|
||||||
| Component | Size | Action |
|
| Component | Size | Action |
|
||||||
|
|||||||
Reference in New Issue
Block a user