Skip to main content

Cloud·15 min read·

Building a Private Cloud in Your Homelab with Proxmox and Security Best Practices

Learn to build and secure a production-grade private cloud using Proxmox VE. Covers network segmentation, backup strategies, security hardening, and resource management with real homelab implementation lessons.

Proxmox VE turned my homelab from a collection of physical machines into a proper private cloud. After 18 months of production use, I’ve learned which configurations matter and which “best practices” are actually marketing fluff.

Here’s what succeeded, what failed spectacularly, and how to build a secure private cloud that won’t drive you crazy.

your cloud, under your own roof

Why Private Cloud Architecture Matters

Public cloud providers offer convenience. But data sovereignty, compliance requirements, and cost control drive many organizations toward private cloud solutions. In my homelab, I needed to test enterprise patterns without enterprise budgets.

Why it matters: Understanding private cloud fundamentals lets you architect solutions that scale from homelab to production environments.

The Foundation: Proxmox VE Architecture

Proxmox VE combines KVM virtualization and LXC containers in a single management interface. It’s Debian-based with a web UI that doesn’t make you want to throw things.

My setup runs on a single Dell R910:

  • 256GB RAM
  • 4x Intel Xeon E7540 (24 cores/48 threads total)
  • ~400GB mixed storage (LVM for OS + ZFS pool for VMs/data)
  • Backed by TrueNAS SCALE with ~30TB usable storage (RAIDZ2)

This single node handles 30+ VMs and containers comfortably. With 256GB RAM, careful resource allocation is key, but it’s more than sufficient for a full-featured homelab. Uptime averages 99.7% - better than some cloud providers I’ve used.

Proxmox VE Host4x Xeon E7540, 256GB RAM30+ VMsLXC ContainersZFS Pool - OS + VM Storage
UDM Pro - Firewall / RouterUniFi Switch 24 PoE
TrueNAS SCALE~30TB usable, RAIDZ2
Proxmox manages compute locally, connects to Ubiquiti for management and VM traffic, and uses TrueNAS over iSCSI for shared storage.

Storage Architecture That Actually Works

Proxmox supports multiple storage backends. I tested five configurations over 12 months:

Local storage: Fast, simple, no redundancy. Fine for testing, terrible for production.

Ceph: Distributed, self-healing, complex to tune. I spent 40 hours fighting OSD performance issues before giving up.

ZFS over iSCSI: My current solution. TrueNAS SCALE provides the storage, Proxmox consumes it via iSCSI. Reliable, fast enough, manageable complexity.

GlusterFS: worth noting this option has since gone away — it is archived upstream and no longer appears in the PVE storage table at all. At the time it seemed promising. Performance was inconsistent - VMs would randomly stutter during file operations.

NFS: the most feature-complete of the lot, actually — PVE supports images, containers, templates, ISOs, backups and snippets on it, with snapshots on qcow2 images. It is file-level, so raw-image performance lags block storage.

Winner for VM disks: ZFS over iSCSI. Its Proxmox content type is images only in the storage plugin I inspected, so backups, ISOs, templates, and container root directories need a separately supported file-level target. My TrueNAS SCALE server provides ~30TB usable storage (from 40TB raw) with RAIDZ2 protection. Proxmox sees the iSCSI target as shared block storage for VM disks; it is not the backup destination.

Proxmox VE
ZFS PoolVM disks, fast
TrueNAS SCALERAIDZ2 Pool40TB raw to 30TB usable
Proxmox uses local disks directly and reaches the TrueNAS RAIDZ2 pool over iSCSI.

Network Segmentation Strategy

Default Proxmox networking puts everything on one bridge. That’s fine for homelabs, dangerous for production workloads.

I implemented five VLANs using my Ubiquiti Dream Machine Pro and UniFi Switch 24 PoE:

Management Network (VLAN 10): Proxmox host, TrueNAS storage

  • 192.168.10.0/24
  • Isolated from internet
  • SSH access via bastion host only

Service Network (VLAN 20): Production VMs and containers

  • 192.168.20.0/24
  • Internet access through UDM Pro firewall
  • Hosts GitLab CE, BookStack, Jellyfin

IoT Network (VLAN 30): Smart home devices

  • 192.168.30.0/24
  • Heavily restricted
  • Home Assistant bridges to service network

Guest Network (VLAN 40): Visitor access

  • 192.168.40.0/24
  • Internet only, no local resources
  • Isolated by UDM Pro

Lab Network (VLAN 50): K3s cluster on Raspberry Pis

  • 192.168.50.0/24
  • 3x Pi 5 (16GB) + 1x Pi 4 (8GB)
  • Isolated testing environment

Each VLAN has specific firewall rules enforced by the Dream Machine Pro. Cross-VLAN communication requires explicit allow rules. The UniFi ecosystem makes this manageable through a single interface.

InternetUDM Profirewall / router
Proxmox HostTrueNASBastion Host
GitLab CEBookStackJellyfin
Home AssistantSmart Devices
Guest Devices - Internet Only
K3s Cluster3x Pi 5 + 1x Pi 4
The UDM Pro routes each VLAN; Home Assistant bridges only to approved services, and bastion SSH is the management entry point.

Security Hardening That Matters

Standard Proxmox installation is reasonably secure. But “reasonably secure” isn’t secure enough for anything important.

Host-Level Security

Disable root SSH access: Create dedicated admin user with sudo privileges.

# Create admin user
useradd -m -s /bin/bash proxmox-admin
install -d -m700 -o proxmox-admin ~proxmox-admin/.ssh
# Put your public key in ~proxmox-admin/.ssh/authorized_keys BEFORE going on.
# A fresh account has no password and no key: it cannot log in by either route.

# PVE does not ship sudo. usermod against a group with no sudoers entry
# succeeds silently and grants nothing.
apt install -y sudo && usermod -aG sudo proxmox-admin

# In a SECOND terminal, prove it works before you close the door:
#   ssh proxmox-admin@host sudo -v

# Match commented and uncommented forms. A literal 's/PermitRootLogin yes/'
# no-ops if the directive is commented or lives in an sshd_config.d/ drop-in.
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sshd -t && systemctl restart ssh

Enable fail2ban: Protects against brute force attacks.

apt update && apt install fail2ban
systemctl enable --now fail2ban     # without --now it waits for the next boot

# Debian's default jails cover sshd ONLY. The Proxmox web UI on 8006
# authenticates through pvedaemon and needs its own jail, matching
#   pvedaemon\[.*authentication failure; rhost=<HOST>
# Given that this whole setup routes admins to the web UI, that is the one
# door stock fail2ban is not watching.

Configure automatic updates: Security patches matter more than uptime.

apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

# Debian's shipped Origins-Pattern matches ONLY the Debian security origin.
# The Proxmox repos are a different origin, so pve-kernel, pve-manager,
# qemu-server and pve-qemu-kvm are NEVER upgraded by the default config.
# Add it explicitly in /etc/apt/apt.conf.d/50unattended-upgrades:
#   Unattended-Upgrade::Origins-Pattern {
#     "origin=Debian,codename=${distro_codename},label=Debian-Security";
#     "origin=Proxmox";
#   };
# Note also that unattended-upgrades does not reboot by default, so a new
# kernel sits on disk unbooted until you do something about it.

I learned this the hard way when a VM guest broke out to the host via a kernel vulnerability. The exploit was public for 3 weeks. Automatic patching would have prevented it.

Certificate management: Default Proxmox uses self-signed certificates. I replaced them with Let’s Encrypt certs via DNS challenges.

The process took 6 attempts to get right. ACME client configuration is finicky, but valid certificates prevent browser warnings and MITM attacks.

VM and Container Security

Template hardening: I maintain golden images for Ubuntu 24.04, Debian 12, and Alpine Linux. Each template includes:

  • Disabled default accounts
  • SSH key authentication only
  • Fail2ban configured
  • Automatic security updates
  • Minimal package installation

Resource limits: Every VM and container has CPU, RAM, and disk limits. Prevents resource exhaustion attacks.

Network isolation: this is the control people assume they have and usually don’t. The Proxmox firewall is disabled by default at every level — you need the datacenter enable flag, the node flag, and the per-NIC flag on each guest before any rule does anything. Until all three are set, VMs on the same bridge talk freely at layer 2 and your default-deny is a default-allow. Open a second SSH session before you turn it on.

Backup encryption: vzdump only supports encryption when the target is a Proxmox Backup Server storage. To a plain NFS or directory target you get compression and no encryption at all — worth knowing before you assume otherwise. Keys stored on separate system.

Monitoring and Alerting

My monitoring stack combines multiple tools for end-to-end visibility:

Wazuh: Security monitoring and SIEM functionality. Tracks authentication, file changes, vulnerability detection.

Prometheus + Grafana: Performance metrics and visualization. Resource usage, network traffic, service health.

Netdata: Real-time performance monitoring with 1-second granularity. Perfect for troubleshooting performance issues.

I get alerts for:

  • Node CPU >80% for 5 minutes
  • Storage >90% full
  • Failed backups
  • Network connectivity issues
  • Temperature anomalies

Alert fatigue is real. I started with far more alert rules than I could act on and pruned hard that actually matter.

Backup Strategy That Survived Disasters

Backups are boring until you need them. I learned this during a storage controller failure that corrupted 12 VMs.

Three-Tier Backup Strategy

Tier 1 - Local snapshots: ZFS snapshots on TrueNAS every hour, retained for 48 hours. Fast recovery for user errors.

Tier 2 - Proxmox Backup Server: PBS is what makes this tier work. Plain vzdump has no incremental mode — every mode (stop, suspend, snapshot) produces a full archive. Incremental backup via dirty bitmaps, and client-side AES-256-GCM, are both PBS features. 30-day retention on ~30TB RAIDZ2 pool.

Tier 3 - Offsite replication: Restic backups to Backblaze B2. Critical data encrypted and synced daily, full backups weekly. 90-day retention with versioning.

VMs & Containers
ZFS Snapshotsevery hour, 48h retention
Weekly Full BackupDaily IncrementalsTrueNAS RAIDZ230-day retention
Restic EncryptedBackblaze B290-day retention
Local snapshots handle fast rollback, on-site backups cover VM recovery, and encrypted Restic syncs critical data offsite.

Backup Testing (The Part Everyone Skips)

Monthly recovery tests validate backup integrity. I restore random VMs to isolated network, verify functionality.

Results over 12 months: out of roughly a dozen restores, one or two came back missing config files or network settings. Nothing failed outright. Percentages would be false precision on a sample that small — and note that “89% succeeded, 11% had minor issues, 0 failures” does not partition anyway: if the issues were minor and nothing failed, everything restored.

The testing caught several backup corruption issues early. Time investment: 2 hours monthly. Value: priceless when disasters happen.

Restoration Procedures

Document the restore process before you need it. Include:

  • Which backups to restore from
  • Network reconfiguration steps
  • Service startup sequence
  • Validation procedures

I keep restore procedures printed and in a binder. Digital copies are useless when the Proxmox host is down.

Resource Management Lessons

Overcommitting resources is tempting in virtualized environments. Proxmox makes it easy to allocate more CPU and RAM than physically available.

CPU Overcommitment

With 24 cores/48 threads from the 4x Xeon E7540s, I can afford generous CPU allocation. Started with 2:1 overcommit ratio for dev environments. Production stays at 1:1 for predictable performance.

Rule: watch steal time inside the guests, not on the host. It is a guest-side counter; on bare metal it reads zero no matter how oversubscribed you are.

Memory Balancing

With 256GB RAM, memory management requires planning. Careful allocation is key. Fixed allocations are more predictable than dynamic ballooning.

Current allocation: ~180GB to VMs/containers, leaving ~70GB for host OS, ZFS ARC caching, and burst workloads. It’s a healthy balance between utilization and headroom.

Storage Performance

Network storage creates bottlenecks. I measured storage performance across different workloads:

  • Database VMs: 150-300 IOPS avg, 2000 IOPS peak
  • Web servers: 50-100 IOPS avg, 500 IOPS peak
  • File servers: 20-50 IOPS avg, 800 IOPS peak

Storage network sizing is worth doing on paper before spending money. At the IOPS figures above, whether 1GbE suffices depends entirely on block size — around 3,300 IOPS is roughly 216 Mbps at 8 KiB blocks and about 1.7 Gbps at 64 KiB. Which of those you are is the number to measure first, and it is the one I did not write down at the time.

High Availability Strategy (Single Node)

Traditional Proxmox HA requires multiple nodes. With my single Dell R910, I focus on rapid recovery and redundancy at the service level.

Single-Node Resilience

Service-level HA: Critical services like GitLab and Jellyfin run with redundant processes. If one crashes, others continue serving.

Fast VM recovery: with ample RAM and VM disks on the ZFS pool, crashed VMs restart quickly.

Automated recovery: Systemd restart policies and Docker health checks automatically recover failed services.

Future Clustering Plans

When budget allows, the next step is a third node — not a second. Two nodes is not a cluster: with two votes you need two for quorum, so either failure leaves /etc/pve read-only on the survivor and HA impossible. Three nodes, or two plus a QDevice somewhere cheap for the tiebreaker vote. The current setup is designed for easy migration:

# Current network already segregated for clustering
# Shared storage via TrueNAS ready for multi-node access
# VLAN configuration supports cluster heartbeat

For now, the combination of enterprise hardware reliability and service-level redundancy provides adequate uptime for a homelab.

Real-World Failure Modes

Every system fails eventually. Here’s what I’ve encountered and how to handle it:

Storage Controller Failure

Scenario: RAID controller died, corrupted 12 VMs on one node.

Response: Restored from Tier 2 backups. 3-hour RTO, 1-hour RPO.

Lesson: RAID is not backup. Test restore procedures regularly.

Network Switch Failure

Scenario: UniFi Switch 24 PoE stopped responding after firmware update.

Response: Direct connection to Dream Machine Pro for critical services while troubleshooting.

Lesson: Always have a backup switch or at least some unmanaged switches for emergency connectivity.

Certificate Expiration

Scenario: Let’s Encrypt certificates expired, web UI inaccessible.

Response: Used SSH access to renew certificates manually.

Lesson: Monitor certificate expiration dates. ACME automation can fail.

Memory Leak in VM

Scenario: Java application had memory leak, tried to consume unlimited RAM.

Response: Hit the 32GB limit I set for that VM. With 256GB total and proper limits, other services weren’t affected.

Lesson: Resource limits are critical. Can’t rely on massive buffers - must enforce boundaries.

Security Pattern Analysis

During vulnerability testing, I discovered several attack paths in my initial configuration:

VM escape via shared storage: VMs could access other VM disk images through NFS mount points.

Cross-VLAN routing: Firewall rules weren’t properly applied to VM traffic.

Backup access: Backup credentials stored in plaintext configuration files.

Management interface exposure: Proxmox web UI was accessible from DMZ network.

Each issue required different mitigation strategies. The fixes took 3 weeks to implement and test properly.

Security Monitoring Improvements

  • Network monitoring: Deploy security monitoring on each VLAN
  • Access logging: Log all administrative actions
  • Configuration baselines: Track changes to critical configurations
  • Vulnerability scanning: Monthly scans of all VMs and containers

Performance Optimization

Default Proxmox configuration works but isn’t optimized for specific workloads.

VM Performance Tuning

CPU topology: Match VM CPU configuration to physical CPU layout. NUMA awareness matters for memory-intensive workloads.

Disk caching: Use writeback caching for development VMs, writethrough for production. The performance difference is significant - writeback cache improved database performance by 40%.

Network drivers: VirtIO drivers provide better performance than emulated hardware. All my VMs use VirtIO for network and storage.

Cluster Performance

A note on clustering, since this comes up: none of it applies to a single node. There is no corosync ring to tune and nothing to migrate to. Worth stating because most Proxmox tuning advice online assumes a cluster.

Storage optimization: Enabled compression on ZFS datasets. 25% space savings with minimal CPU overhead.

Cost Analysis and ROI

Building private cloud infrastructure requires upfront investment. Here’s my cost breakdown:

Hardware: a used enterprise server, networking equipment and disks. A second-hand R910 is a few hundred dollars; the switching cost more than the compute did. Software: $0 (Proxmox is open source) Electricity: $150/month average Maintenance: 4-6 hours/month

Equivalent cloud costs: genuinely hard to state honestly. Matching 48 threads of 2010-era Westmere-EX against modern vCPU overcounts the homelab, matching the RAM undercounts it, and Savings Plans move the answer by another 40%. for similar compute capacity.

ROI: the software is free and the electricity is the recurring cost. The number that actually decides it is the 4-6 hours a month of maintenance, which nobody budgets for and which is the real reason to rent instead.

Hidden costs: Learning curve, maintenance time, backup storage. Factor these into planning.

Lessons Learned

After 18 months of production use, here’s what I wish I’d known from the start:

Network design matters most: Poor network segmentation causes security and performance problems that are expensive to fix later.

Start simple, evolve complexity: My initial design was over-engineered. Simple solutions succeed where complex solutions fail.

Documentation saves time: write it while building, not after. The version written afterwards documents what you think you did.

Backup testing is non-negotiable: Untested backups aren’t backups. Schedule regular recovery tests.

Security is a process: Regular vulnerability assessments, patch management, and access reviews prevent most security issues.

Performance monitoring is essential: You can’t optimize what you don’t measure. Deploy monitoring early.

Next Steps for Your Implementation

Phase 1: Install Proxmox on single node, experiment with VMs and containers.

Phase 2: Add shared storage, implement backup strategy.

Phase 3: Build cluster with multiple nodes, configure HA.

Phase 4: Implement network segmentation and security hardening.

Phase 5: Deploy monitoring, alerting, and documentation.

Phase 6: Regular security assessments and performance optimization.

Don’t try to implement everything at once. Each phase builds on previous work and provides learning opportunities.

Sources

Building a private cloud takes patience and iteration. Start small, learn continuously, and don’t be afraid to rebuild when you discover better approaches. The knowledge gained is worth the effort invested.