Turn your fresh Proxmox installation into an optimized, secure, and high-performance virtualization host
π Documentation β’ π Quick Start β’ π‘ Features β’ π€ Contributing
- π― Supported Versions
- π Quick Start
- π§° Ansible Automation
- π‘ Features
- π¦ Installation Scripts
- π Hosting Provider Guides
- πΎ ZFS Management
- π Networking
- π οΈ Helper Scripts
- π Additional Notes
- π€ Contributing
- π License
| Platform | Version | Debian | Status |
|---|---|---|---|
| Proxmox VE | 9.x | Trixie (13) | β Fully Supported |
| Proxmox VE | 8.x | Bookworm (12) | β Fully Supported |
| Proxmox Backup Server | 3.x | Bookworm (12) | β Fully Supported |
Run this command on a fresh Proxmox installation to apply all optimizations:
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/install-post.sh -c -O install-post.sh && bash install-post.sh && rm install-post.shπ‘ Note: Reboot after installation to apply all changes.
For repeatable, idempotent automation, use the Ansible roles and playbooks in ansible/.
- Full
ansiblepackage (ansible-core is not supported) - Python 3.11+
- Collections:
ansible.utils,ansible.posix
cd ansible
# Install required collections
ansible-galaxy collection install -r collections/requirements.yml
# Configure inventory
cp inventory/hosts.ini.example inventory/hosts.ini
nano inventory/hosts.ini
# Run full optimization
ansible-playbook playbooks/proxmox.yml -i inventory/hosts.ini| Role | Description |
|---|---|
proxmox_base |
Repositories, packages, APT configuration |
proxmox_security |
Fail2ban, Lynis, rpcbind hardening |
proxmox_tuning |
Sysctl, journald, KSM, MOTD, limits |
proxmox_zfs |
ZFS ARC tuning, auto-snapshots |
proxmox_vfio |
IOMMU, VFIO for PCIe passthrough |
proxmox_networking |
vmbr0 routed bridge configuration |
proxmox_lxc_docker |
Docker support for LXC containers |
proxmox_nvidia |
NVIDIA Docker runtime for GPU passthrough |
proxmox_zfs_slog_cache |
Convert MD RAID to ZFS SLOG/cache |
proxmox_tinc_vpn |
Tinc VPN mesh network for clusters |
provider_ovh |
OVH RTM installer, auto-detection |
provider_hetzner |
Hetzner network tuning, Storage Box |
All variables can be customized in inventory/group_vars/all.yml:
# Security
xs_fail2ban: "yes"
xs_disablerpc: "yes"
xs_lynis: "yes"
# Performance
xs_tcpbbr: "yes"
xs_ksmtuned: "yes"
xs_pigz: "yes"
# ZFS
xs_zfsarc: "yes"
xs_zfsautosnapshot: "no"Some playbooks perform destructive operations and require explicit confirmation:
# Network configuration (overwrites /etc/network/interfaces)
ansible-playbook playbooks/network-configure.yml -e dangerous_confirm=yes
# LVM to ZFS conversion
ansible-playbook playbooks/lvm-to-zfs.yml -e dangerous_confirm=yes
# ZFS pool creation
ansible-playbook playbooks/zfs-create.yml -e dangerous_confirm=yes
# ZFS SLOG/cache (converts MD RAID - destructive!)
ansible-playbook playbooks/zfs-slog-cache.yml
# Docker in LXC (security-sensitive)
ansible-playbook playbooks/lxc-docker.yml -e lxc_docker_container_id=100 -e lxc_docker_confirm=trueDeploy Tinc VPN across multiple nodes:
# Configure inventory with per-host variables
# inventory/hosts.ini:
# [proxmox_nodes]
# node1 tinc_vpn_ip_last=1 tinc_connect_to=node2
# node2 tinc_vpn_ip_last=2 tinc_connect_to=node3
# node3 tinc_vpn_ip_last=3 tinc_connect_to=node1
ansible-playbook playbooks/tinc-vpn.yml -i inventory/hosts.iniNever store credentials in version control. Use host_vars/ with ansible-vault:
# Create encrypted host vars
ansible-vault create inventory/host_vars/myhost/vault.yml
# Run playbook with vault
ansible-playbook playbooks/proxmox.yml --ask-vault-pass- ansible/README.md - Full Ansible documentation
- MIGRATION.md - Migration guide from shell scripts
- ansible/playbooks/README.md - Playbook reference
The post-installation script (install-post.sh) transforms your Proxmox host with:
|
|
The main optimization script that configures over 30+ system improvements.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/install-post.sh -c -O install-post.sh
bash install-post.shCreate a configuration file for custom options:
# Download sample configuration
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/install-post.env.sample -c -O install-post.env
# Edit configuration
nano install-post.env
# Run with custom settings
bash install-post.sh# Example: Disable MOTD banner
export XS_MOTD="no"
bash install-post.shBy default, output is written to /var/log/ashimov-install-post.log. Disable or change it with:
export XS_LOG_FILE=""
export XS_LOG_FILE="/path/to/custom.log"π Click to view all configuration options
| Variable | Default | Description |
|---|---|---|
XS_AMDFIXES |
yes | AMD EPYC/Ryzen CPU optimizations |
XS_APTIPV4 |
yes | Force APT to use IPv4 |
XS_APTUPGRADE |
yes | Update system packages |
XS_BASHRC |
yes | Customize bash shell |
XS_CEPH |
no | Install Ceph storage |
XS_DISABLERPC |
yes | Disable portmapper/rpcbind |
XS_ENTROPY |
yes | Entropy pool management |
XS_FAIL2BAN |
yes | Web interface protection |
XS_GUESTAGENT |
yes | VM guest agent detection |
XS_IFUPDOWN2 |
yes | Rebootless networking |
XS_JOURNALD |
yes | Optimize journald |
XS_KERNELHEADERS |
yes | Install kernel headers |
XS_KERNELPANIC |
yes | Auto-reboot on panic |
XS_KSMTUNED |
yes | KSM memory optimization |
XS_LIMITS |
yes | Increase system limits |
XS_LOGROTATE |
yes | Optimize log rotation |
XS_LOG_FILE |
/var/log/ashimov-install-post.log | Install-post log file (empty to disable) |
XS_LYNIS |
yes | Security scanning tool |
XS_CISOFY_KEY_URL |
https://packages.cisofy.com/keys/cisofy-software-public.key | Override Cisofy key URL |
XS_MAXFS |
yes | Increase FS limits |
XS_MEMORYFIXES |
yes | Memory optimizations |
XS_MOTD |
yes | Custom MOTD banner |
XS_NET |
yes | Network optimizations |
XS_MANAGE_SOURCES_LIST |
yes | Manage /etc/apt/sources.list (clean installs) |
XS_NOENTREPO |
yes | Disable enterprise repo |
XS_PROXMOX_KEY_URL |
empty | Override Proxmox key URL (auto by OS codename if empty) |
XS_NOSUBBANNER |
yes | Remove subscription banner |
XS_OPENVSWITCH |
no | Install Open vSwitch |
XS_OVHRTM |
yes | OVH RTM monitoring |
XS_OVHRTM_ALLOW_UNVERIFIED |
no | Allow running OVH RTM installer without checksum verification |
XS_OVHRTM_SHA256 |
empty | SHA256 checksum for OVH RTM installer (recommended) |
XS_OVHRTM_URL |
https://last-public-ovh-infra-yak.snap.mirrors.ovh.net/yak/archives/apply.sh | Override OVH RTM installer URL |
XS_PIGZ |
yes | Parallel gzip compression |
XS_SWAPPINESS |
yes | Fix high swap usage |
XS_TCPBBR |
yes | TCP BBR congestion control |
XS_TCPFASTOPEN |
yes | TCP FastOpen |
XS_TESTREPO |
no | Enable testing repo |
XS_TIMESYNC |
yes | NTP time sync |
XS_TIMEZONE |
auto | Set timezone by IP |
XS_IPINFO_URL |
https://ipinfo.io/ip | Override public IP lookup endpoint |
XS_IPAPI_URL |
https://ipapi.co | Override timezone lookup base URL |
XS_UTILS |
yes | Install system utilities |
XS_VZDUMP |
yes | Optimize backup speed |
XS_ZFSARC |
yes | ZFS ARC optimization |
XS_ZFSAUTOSNAPSHOT |
no | ZFS auto-snapshots |
XS_VFIO_IOMMU |
yes | PCIe passthrough support |
Convert a clean Debian installation to Proxmox VE.
curl -O https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/debian-2-proxmox/debian13-2-proxmox9.sh
chmod +x debian13-2-proxmox9.sh
./debian13-2-proxmox9.shcurl -O https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/debian-2-proxmox/debian12-2-proxmox8.sh
chmod +x debian12-2-proxmox8.sh
./debian12-2-proxmox8.shNote: To allow the conversion scripts to download install-post.sh, set XS_ALLOW_REMOTE_INSTALL_POST=yes and XS_INSTALL_POST_SHA256=<expected_sha256>.
Prerequisites:
- Clean Debian installation with valid FQDN hostname
- Tested on KVM, VirtualBox, and Dedicated Servers
- Automatically handles cloud-init and
/etc/hostsconfiguration - Runs post-installation optimizer automatically (local
install-post.shor allow remote download with checksum)
Detailed guide for Hetzner dedicated servers: π Hetzner README
# Proxmox VE 8 (default)
curl -O https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/hetzner/vnc-install-proxmox.sh
chmod +x vnc-install-proxmox.sh
./vnc-install-proxmox.sh
# Proxmox VE 9
./vnc-install-proxmox.sh pve9
# Proxmox Backup Server
./vnc-install-proxmox.sh pbs# From Hetzner Rescue System
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/hetzner/installimage-proxmox.sh -c -O installimage-proxmox.sh
chmod +x installimage-proxmox.sh
# Proxmox VE 8
./installimage-proxmox.sh "your.hostname.fqdn"
# Proxmox VE 9
./installimage-proxmox.sh "your.hostname.fqdn" pve9
# Proxmox Backup Server
./installimage-proxmox.sh "your.hostname.fqdn" pbsDetailed guide for OVH dedicated servers: π OVH README
Quick Setup:
- Select Install from OVH template β VPS Proxmox VE
- Configure partitions (see guide for recommended layout)
- Set installation script URL:
https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/install-post.sh - After installation, run LVM to ZFS conversion and networking scripts
Convert MDADM-based LVM to ZFS with automatic RAID level detection.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/zfs/lvm-2-zfs.sh -c -O lvm-2-zfs.sh
chmod +x lvm-2-zfs.sh
./lvm-2-zfs.sh [LVM_MOUNT_POINT]Creates:
zfsbackup(rpool/backup)zfsvmdata(rpool/vmdata)/var/lib/vz/tmp_backup(rpool/tmp_backup)
Create ZFS pool from specified devices with automatic RAID detection.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/zfs/createzfs.sh -c -O createzfs.sh
chmod +x createzfs.sh
ZFS_CONFIRM=yes ./createzfs.sh poolname /dev/sda /dev/sdb
ZFS_DRYRUN=yes ./createzfs.sh poolname /dev/sda /dev/sdbDry-run prints planned actions and exits non-zero without changes.
RAID Level Detection:
| Drives | RAID Level | Type |
|---|---|---|
| 1 | zfs | Single |
| 2 | mirror | RAID1 |
| 3-5 | raidz-1 | RAID5 |
| 6-10 | raidz-2 | RAID6 |
| 11+ | raidz-3 | RAID7 |
Add L2ARC cache and SLOG to existing ZFS pool.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/zfs/slog-cache-2-zfs.sh -c -O slog-cache-2-zfs.sh
chmod +x slog-cache-2-zfs.sh
./slog-cache-2-zfs.sh poolnameTest ZFS performance with various write patterns.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/zfs/benchmark_zfs.sh -c -O benchmark_zfs.sh
chmod +x benchmark_zfs.sh
./benchmark_zfs.shCreate routed vmbr0 network bridge for Proxmox VMs.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/networking/network-configure.sh -c -O network-configure.sh
chmod +x network-configure.sh
./network-configure.shFeatures:
- vmbr0 (Routed): Public IPs routed through physical interface
- Auto-detects interface, gateway, and netmask
- Supports IPv4 and IPv6
- Creates backup of existing configuration
Create private mesh VPN for cluster communication with multicast support.
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/networking/tincvpn.sh -c -O tincvpn.sh
chmod +x tincvpn.sh
./tincvpn.sh -h3-Node Cluster Example:
# /etc/hosts on all nodes
11.11.11.11 host1
22.22.22.22 host2
33.33.33.33 host3
# Host 1
./tincvpn.sh -i 1 -c host2
# Host 2
./tincvpn.sh -i 2 -c host3
# Host 3
./tincvpn.sh -i 3 -c host1
β οΈ Security Warning: Running Docker in LXC requires elevated privileges.
curl https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/helpers/pve-enable-lxc-docker.sh --output /usr/sbin/pve-enable-lxc-docker
chmod +x /usr/sbin/pve-enable-lxc-docker
pve-enable-lxc-docker <container_id>π‘ Recommendation: Use a dedicated VM for Docker instead of LXC containers.
| Partition | Size | Filesystem | Mount Point |
|---|---|---|---|
| Root | 40 GB | ext4 (RAID1) | / |
| ZFS Cache* | 30 GB | ext4 (RAID1) | /xshok/zfs-cache |
| ZFS SLOG* | 5 GB | ext4 (RAID1) | /xshok/zfs-slog |
| Swap | 16-64 GB** | swap | - |
| Data | Remaining | xfs (LVM) | /var/lib/vz |
*Only for SSD with HDD pool **Based on RAM: <64GB=32GB swap, β₯64GB=64GB swap
apk update && apk add qemu-guest-agent acpi
echo 'GA_PATH="/dev/vport2p1"' >> /etc/conf.d/qemu-guest-agent
rc-update add qemu-guest-agent default
rc-update add acpid default
/etc/init.d/qemu-guest-agent restartpvenode acme account register default mail@example.com
pvenode config set --acme domains=proxmox.example.com
pvenode acme cert order# List all snapshots
zfs list -t snapshot
# Create pre-rollback snapshot
zfs-auto-snapshot --verbose --label=prerollback -r //
# Rollback to snapshot
zfs rollback <snapshotname>For security, always verify downloaded scripts before execution. Use SHA256 checksums to ensure script integrity.
# Download the script
wget https://raw.githubusercontent.com/ashimov/proxmox-optimizer/master/install-post.sh
# Generate checksum and compare with published value
sha256sum install-post.sh
# Or verify in one command (replace EXPECTED_CHECKSUM with actual value)
echo "EXPECTED_CHECKSUM install-post.sh" | sha256sum -c -| Script | Checksum Variable | Allow Unverified Variable |
|---|---|---|
install-post.sh |
XS_INSTALL_POST_SHA256 |
XS_ALLOW_REMOTE_INSTALL_POST |
| OVH RTM installer | XS_OVHRTM_SHA256 |
XS_OVHRTM_ALLOW_UNVERIFIED |
| Hetzner post-install | MY_POSTINSTALL_SHA256 |
MY_POSTINSTALL_ALLOW_UNVERIFIED |
# Set the expected SHA256 checksum (get from releases or compute yourself)
export XS_INSTALL_POST_SHA256="your_checksum_here"
export XS_ALLOW_REMOTE_INSTALL_POST="yes"
# Run the conversion script - it will verify the checksum before execution
./debian12-2-proxmox8.sh
β οΈ Important: Never set*_ALLOW_UNVERIFIED=yesin production. Always use checksums.
Contributions are welcome! Please feel free to submit Pull Requests.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the BSD License - see the LICENSE file for details.