Proxmox Post-Install Checklist: 15 Things to Configure First
Essential post-installation checklist for Proxmox VE covering repository setup, security hardening, storage config, and performance tuning.
On this page
A fresh Proxmox install works out of the box, but "works" and "ready for production" aren't the same thing. Over the years I've built up a checklist that I run through on every new node before I start deploying workloads. Some of these are mandatory (like switching repos), some are best practices, and a few are quality-of-life improvements that you'll thank yourself for later.
I'm listing these roughly in the order you should do them. Some steps depend on earlier ones, so resist the urge to skip around.
1. Switch to the No-Subscription Repository
By default, Proxmox points at the enterprise repository, which requires a paid subscription. If you try to run apt update on a fresh install without a subscription, you'll get a 401 error:
apt update
# Err:1 https://enterprise.proxmox.com/debian/pve bookworm InRelease
# 401 Unauthorized
Fix it by disabling the enterprise repo and enabling the no-subscription repo:
# Comment out the enterprise repo
sed -i 's/^deb/#deb/' /etc/apt/sources.list.d/pve-enterprise.list
# Also disable the ceph enterprise repo if present
sed -i 's/^deb/#deb/' /etc/apt/sources.list.d/ceph.list 2>/dev/null
# Add the no-subscription repo
cat > /etc/apt/sources.list.d/pve-no-subscription.list << 'EOF'
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription
EOF
The no-subscription repo is tested but doesn't get the same level of QA as the enterprise channel. For a homelab, it's perfectly fine. I've been running it across a dozen nodes for years without issues.
2. Update All Packages
Now that repos are sorted:
apt update && apt full-upgrade -y
If there's a kernel update, reboot after:
# Check if a reboot is needed
ls /var/run/reboot-required 2>/dev/null && echo "Reboot required" || echo "No reboot needed"
reboot
3. Disable the Subscription Nag Popup
Every login in the web UI shows "No valid subscription." It's harmless but annoying. Patch it out:
sed -Ei.bak "s/NotFound/Active/g; s/notfound/active/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
systemctl restart pveproxy.service
Hard-refresh your browser (Ctrl+Shift+R) after applying. This gets overwritten on proxmox-widget-toolkit package updates, so you'll need to reapply occasionally.
4. Configure NTP / Time Synchronization
Accurate time is critical for clusters, TOTP authentication, certificate validation, and log correlation. Proxmox uses chrony by default on 8.x:
# Verify chrony is running
systemctl status chronyd
# Check sync status
chronyc tracking
Reference ID : A29FC801 (time.cloudflare.com)
Stratum : 3
Ref time (UTC) : Sat Mar 07 14:22:31 2026
System time : 0.000012345 seconds fast of NTP time
If you prefer specific NTP servers (like an internal one), edit /etc/chrony/chrony.conf:
# Comment out the default pool and add your preferred servers
cat > /etc/chrony/chrony.conf << 'EOF'
server time.cloudflare.com iburst
server time.google.com iburst
server pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
EOF
systemctl restart chronyd
chronyc sources
5. Set Up Email Notifications
Proxmox sends email alerts for failed backup jobs, ZFS errors, disk SMART warnings, and cron output. By default it tries to send via the local MTA, which usually doesn't work without configuration.
I use a simple Postfix relay through an SMTP service. Here's a setup for Gmail's SMTP (works with any SMTP relay):
apt install -y libsasl2-modules
# Configure postfix as a relay
cat >> /etc/postfix/main.cf << 'EOF'
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
EOF
# Set up credentials (use an App Password, not your actual Gmail password)
echo "[smtp.gmail.com]:587 youraddress@gmail.com:your-app-password" > /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd
postmap /etc/postfix/sasl_passwd
systemctl restart postfix
# Test it
echo "Proxmox test email from $(hostname)" | mail -s "PVE Alert Test" youraddress@gmail.com
Check your inbox. If nothing arrives, look at /var/log/mail.log for errors. The most common issue is Gmail blocking "less secure" apps — use an App Password from your Google account security settings.
6. Install Useful System Packages
The base install is minimal. These packages are things I always end up needing:
apt install -y htop iotop iftop tmux vim curl wget net-tools dnsutils \
lm-sensors ethtool smartmontools lsof strace sysstat
Quick rundown on why each matters:
- htop — better process viewer than
top - iotop — find which process is hammering your disk
- iftop — real-time network bandwidth per connection
- tmux — persistent terminal sessions (essential for long-running tasks over SSH)
- smartmontools — monitor disk health via SMART (
smartctl -a /dev/sda) - lm-sensors — CPU/board temperature monitoring (
sensorscommand) - sysstat — historical system performance data (
sar,iostat)
After installing lm-sensors, run the detection:
sensors-detect --auto
sensors
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +42.0°C (high = +80.0°C, crit = +100.0°C)
Core 0: +39.0°C (high = +80.0°C, crit = +100.0°C)
Core 1: +41.0°C (high = +80.0°C, crit = +100.0°C)
Core 2: +40.0°C (high = +80.0°C, crit = +100.0°C)
Core 3: +42.0°C (high = +80.0°C, crit = +100.0°C)
7. Configure Storage Layout
The default install creates two storage targets:
- local — a directory at
/var/lib/vzfor ISOs, container templates, backups, and snippets - local-lvm — an LVM-thin pool for VM disk images and container volumes
This is a reasonable default. Where people run into trouble is trying to store everything on local. VM disk images belong on local-lvm (or a dedicated ZFS pool, or NFS share). Disk images on a directory-type storage work but you lose thin provisioning and snapshot performance.
If you have additional disks, now is the time to set them up. For a dedicated VM storage disk:
# Wipe the disk
wipefs -a /dev/sdb
# Create a new LVM setup
pvcreate /dev/sdb
vgcreate vmstorage /dev/sdb
lvcreate -l 95%FREE -n vmdata vmstorage -T
# Add it in the GUI: Datacenter > Storage > Add > LVM-Thin
# Or via CLI:
pvesm add lvmthin vmstorage --vgname vmstorage --thinpool vmdata --content images,rootdir
For ZFS (if you have two matching disks for a mirror):
# Create a ZFS mirror pool
zpool create -f tank mirror /dev/sdb /dev/sdc
# Add to Proxmox
pvesm add zfspool tank-storage --pool tank --content images,rootdir
8. Enable IOMMU for PCI Passthrough
If you ever want to pass a GPU, NIC, or any other PCIe device directly to a VM, you need IOMMU enabled at the kernel level. Even if you don't need it now, it's easier to enable it upfront.
For Intel CPUs, edit GRUB:
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="quiet"/GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"/' /etc/default/grub
update-grub
For AMD CPUs:
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="quiet"/GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"/' /etc/default/grub
update-grub
If you're booting via systemd-boot (UEFI without GRUB), edit the kernel command line in /etc/kernel/cmdline instead and run proxmox-boot-tool refresh.
Load the required kernel modules:
cat >> /etc/modules << 'EOF'
vfio
vfio_iommu_type1
vfio_pci
EOF
Reboot, then verify:
dmesg | grep -e DMAR -e IOMMU
# Should see something like:
# [ 0.012345] DMAR: IOMMU enabled
9. Set Up a Second Network Bridge
The default vmbr0 bridge connects to your physical NIC and shares the management network with your VMs. This works but it means VM traffic and management traffic share the same interface.
If you have a second NIC, create a separate bridge for VM traffic. In /etc/network/interfaces:
cat >> /etc/network/interfaces << 'EOF'
auto vmbr1
iface vmbr1 inet manual
bridge-ports ens19
bridge-stp off
bridge-fd 0
#VM Network - VLAN Trunk
EOF
# Apply without rebooting
ifreload -a
You can also do this through the GUI: Node > Network > Create > Linux Bridge. Set ens19 (or whatever your second NIC is) as the bridge port and leave the IP fields empty since this bridge just carries VM traffic.
If you only have one NIC but want to separate traffic, you can use VLAN-aware bridging instead:
# In /etc/network/interfaces, modify vmbr0:
auto vmbr0
iface vmbr0 inet static
address 192.168.1.50/24
gateway 192.168.1.1
bridge-ports eno1
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
Then assign VLANs to individual VMs in their network device settings.
10. Configure Firewall Basics
Proxmox has a built-in firewall that operates at the datacenter, node, and VM level. It's disabled by default. I recommend enabling it at the datacenter level and creating rules from the top down.
Through the GUI: Datacenter > Firewall > Options > set Firewall to "Yes."
Then add input rules for the management interface:
# Allow SSH
pve-firewall add rule --action ACCEPT --type in --dport 22 --proto tcp --enable 1
# Allow web UI
pve-firewall add rule --action ACCEPT --type in --dport 8006 --proto tcp --enable 1
# Allow VNC console
pve-firewall add rule --action ACCEPT --type in --dport 5900:5999 --proto tcp --enable 1
# Allow SPICE console
pve-firewall add rule --action ACCEPT --type in --dport 3128 --proto tcp --enable 1
Watch out: if you enable the firewall without adding rules for SSH and port 8006 first, you will lock yourself out. Don't ask me how I know. If this happens, you can disable the firewall from the node console by editing /etc/pve/firewall/cluster.fw and setting enable: 0.
11. Set Up Scheduled Backups
Backups are non-negotiable. Set up at least a weekly backup for all VMs and containers.
Through the GUI: Datacenter > Backup > Add.
My typical backup config:
- Schedule: Daily at 02:00
- Storage: A dedicated backup storage (NFS share, PBS, or local directory)
- Mode: Snapshot (doesn't require stopping the VM)
- Compression: ZSTD (best ratio/speed balance)
- Retention: Keep last 7 daily, 4 weekly, 3 monthly
Or set it up via CLI:
cat > /etc/pve/jobs.cfg << 'EOF'
vzdump: backup-daily
enabled 1
schedule 02:00
storage local
mailnotification failure
mode snapshot
compress zstd
all 1
prune-backups keep-daily=7,keep-weekly=4,keep-monthly=3
EOF
If you have a Proxmox Backup Server, use that instead of local vzdump backups. PBS gives you incremental backups, deduplication, and integrity verification. It's a massive storage savings.
12. Enable SMART Monitoring
Your disks will fail. The question is whether you get warning signs first. SMART monitoring gives you those signs:
# Check if SMART is supported and enabled
smartctl -i /dev/sda | grep -i smart
SMART support is: Available
SMART support is: Enabled
# Run a short self-test
smartctl -t short /dev/sda
# View results after a few minutes
smartctl -a /dev/sda
Set up periodic SMART checks by editing /etc/smartd.conf:
cat > /etc/smartd.conf << 'EOF'
# Monitor all disks, run short self-test weekly, long monthly
# Send email on any health change
DEVICESCAN -d auto -n standby -H -l error -l selftest -f \
-s (S/../.././02|L/../../1/03) \
-m root -M exec /usr/share/smartmontools/smartd-runner
EOF
systemctl restart smartd
13. Configure CPU Governor
By default, Proxmox might use the ondemand or schedutil CPU governor. For a server that's always on and running VMs, performance mode eliminates frequency scaling latency:
# Check current governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
schedutil
# Set performance mode
apt install -y cpufrequtils
echo 'GOVERNOR="performance"' > /etc/default/cpufrequtils
systemctl restart cpufrequtils
# Verify
cpufreq-info | grep "current policy"
current policy: frequency should be within 800 MHz and 4.20 GHz.
The governor "performance" may decide which speed to use
If power consumption matters (homelab in a closet that runs 24/7), leave it on schedutil. The power savings are real — I measured a 15-20W difference on an R730 at idle.
14. Add a Let's Encrypt SSL Certificate
The default self-signed certificate works but generates browser warnings. If your Proxmox host has a public DNS name (or you're using a split-horizon DNS), you can get a real cert via ACME:
Through the GUI: Node > Certificates > ACME.
- Add an ACME account (Let's Encrypt production or staging)
- Add a domain entry for your node's FQDN
- Choose HTTP challenge (port 80 must be accessible) or DNS challenge (works behind NAT)
- Click "Order Certificate Now"
For internal-only setups, I find it easier to just accept the self-signed cert or set up a wildcard cert from your own CA. The browser warning is a minor annoyance, not a security issue — you're connecting to a server on your own network.
15. Set a DNS Domain and Search Path
Small thing, but it matters. Set your node's DNS search domain properly so short hostnames resolve:
# In /etc/resolv.conf (managed by Proxmox, edit via GUI or /etc/network/interfaces)
cat /etc/resolv.conf
search homelab.local
nameserver 192.168.1.1
nameserver 1.1.1.1
You can also configure this in the GUI under Node > DNS. Having a proper search domain means you can ssh pve2 instead of ssh pve2.homelab.local — small convenience, but it adds up when you're managing multiple nodes.
Bonus: Monitoring with PVE Exporter
If you run Prometheus and Grafana (and you should, if you have more than one node), the Proxmox VE exporter feeds node and VM metrics directly into your monitoring stack. But that's a topic for another post.
Final Thoughts
This checklist takes about 30-45 minutes to run through on a new node. Most of it is copy-paste. I keep a shell script version of this in my homelab git repo and run it on every new install, then spot-check a few things through the GUI.
The difference between a "fresh install" Proxmox node and a "properly configured" one is significant. You get reliable alerts when things break, your disks are monitored, your VMs are backed up, and you're not fighting with repository errors every time you try to update.
Resist the temptation to skip the boring stuff and jump straight into creating VMs. Thirty minutes of setup now saves hours of troubleshooting later.