How to Install Webmin + Virtualmin on Ubuntu 24.04 VPS: Free Open-Source Control Panel
If you want the convenience of a cPanel-style control panel without the monthly licensing bill, Virtualmin GPL is the most mature open-source option on the market. Backed by Webmin (in continuous development since 1997) and maintained by Virtualmin, Inc., it gives you a polished web UI for hosting unlimited domains, mailboxes, databases, and FTP users on a single VPS — entirely free for single-server deployments.
Skip the setup? Launch an Ubuntu 24.04 VPS in 60 seconds and run the Virtualmin installer on a clean, provider-neutral image. Deploy a CloudCore Professional VPS now and follow along.
Table of Contents
What is Webmin + Virtualmin?
Webmin is a browser-based system administration interface for Unix-like servers. First released in 1997 and still actively developed, it wraps common sysadmin tasks — user management, cron jobs, package updates, filesystem permissions, network configuration, firewall rules — into a single, modular web UI on port 10000.
Virtualmin is a Webmin module that turns the panel into a full shared-hosting control panel. It layers virtual host management, DNS zones, mailboxes, databases, and per-user quotas on top of Webmin's core, producing a feature set that closely mirrors cPanel or Plesk. The GPL edition is completely free and sufficient for single-server deployments hosting unlimited domains. The Professional edition (paid) adds multi-server clustering, reseller billing integration, and commercial support — but 95% of VPS operators never need it.
A stock Virtualmin install ships a production-grade hosting stack out of the box:
- Apache 2.4 (or Nginx, optional) for web serving
- BIND 9 for authoritative DNS
- Postfix for outbound SMTP plus inbound mail
- Dovecot for IMAP and POP3 mailbox access
- MariaDB (or MySQL / PostgreSQL) for databases
- ProFTPD for FTP/SFTP uploads
- SpamAssassin + ClamAV for mail filtering
- PHP-FPM with per-domain version selection
- Let's Encrypt integration for free SSL certificates
Why Choose Virtualmin GPL Over cPanel or Plesk?
Commercial panels charge per-account, per-month fees that compound quickly once you host more than a handful of domains. Virtualmin GPL flips that equation — you pay for the VPS and nothing else.
- Zero license cost -- The GPL edition hosts unlimited domains, mailboxes, and databases on a single server at no charge. cPanel Solo starts at ~$15/month for a single account; Admin (up to 5 accounts) runs ~$25/month.
- Mature codebase -- Webmin has been in continuous development for over 25 years. Virtualmin has been refined since 2004. Bugs, edge cases, and integration quirks have largely been sanded down over two decades of production use.
- Full stack ownership -- Virtualmin configures standard Ubuntu packages (Apache, Postfix, BIND, MariaDB). Nothing is proprietary. If you ever uninstall the panel, your sites keep running on the underlying services exactly as before — no lock-in.
- Security updates via apt -- The installer adds an official repository. You get Webmin/Virtualmin security patches through the normal
apt upgradecycle rather than via a black-box auto-updater. - No activation servers, no phone-home -- The GPL edition has no license keys, no activation checks, and no outbound calls to a vendor. It runs fully offline if needed.
- Works on modest hardware -- A 2 GB / 20 GB VPS comfortably runs the full stack with room for a dozen low-traffic sites. Commercial panels typically require 4 GB+ before they perform acceptably.
- Clean CLI -- Every UI action has an equivalent
virtualmincommand-line call, which makes scripting, Ansible automation, and headless provisioning straightforward.
Cost Comparison: Virtualmin GPL vs. Commercial Panels
| Scenario | cPanel Admin (5 accounts) | Plesk Web Pro | Virtualmin GPL |
|---|---|---|---|
| Monthly license | ~$25/mo | ~$20/mo | Free |
| Domain limit | 5 accounts | 30 domains | Unlimited |
| VPS cost (CloudCore Professional) | EUR 19.99/mo | EUR 19.99/mo | EUR 19.99/mo |
| Total monthly cost | ~$50/mo | ~$43/mo | EUR 19.99/mo |
| Multi-server clustering | Included (higher tiers) | Included | Pro edition (paid) |
| Commercial support | Included | Included | Pro edition (paid) |
Prerequisites
Before you begin, make sure you have:
- A freshly installed Ubuntu 24.04 LTS VPS with root SSH access. Virtualmin expects a clean image — running the installer on a server that already has Apache, MySQL, or Postfix configured will cause conflicts.
- At least 2 GB of RAM and 20 GB of disk (4 GB / 40 GB recommended once you start hosting real workloads with SpamAssassin + ClamAV active).
- A registered domain you control the DNS for (you'll point it at your VPS shortly).
- Ports open on your firewall/provider network: 22 (SSH), 25 (SMTP), 53 (DNS), 80/443 (HTTP/S), 110/143/993/995 (POP/IMAP), 587 (submission), 10000 (Webmin).
Recommended Plan: CloudCore Professional>
For a Virtualmin host serving a dozen or so low-to-medium-traffic domains, the CloudCore Professional plan gives you all the headroom you need:>
- 6 vCPU cores
- 12 GB RAM
- 100 GB NVMe SSD
- Unmetered bandwidth
- EUR 19.99/month>
ClamAV alone wants ~1 GB RAM resident, and PHP-FPM pools scale with visitor count — 12 GB keeps everything comfortable without swapping.
Connect to your fresh VPS via SSH:
ssh root@your-server-ipStep 1: Prepare a Fresh Ubuntu 24.04 Install
Virtualmin's installer assumes a minimal, up-to-date base system. Bring the package index current and apply any pending security updates before you start.
apt update && apt upgrade -yExpected output (abbreviated):
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Reading package lists... Done
Building dependency tree... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.If the kernel was updated, reboot:
rebootReconnect after a minute and continue. Do not manually install Apache, Nginx, Postfix, MariaDB, or BIND at this point — the installer will pull those packages with the exact configuration Virtualmin expects.
Step 2: Set a Fully Qualified Hostname
Virtualmin requires the server's hostname to be a fully qualified domain name (FQDN) that resolves via DNS — for example panel.example.com, not just ubuntu or vps. The installer's pre-flight check will refuse to run otherwise, and Postfix will reject mail with a short hostname.
Set the FQDN:
hostnamectl set-hostname panel.example.comAdd the FQDN to /etc/hosts so it resolves locally even before DNS propagates:
echo "$(hostname -I | awk '{print $1}') panel.example.com panel" >> /etc/hostsVerify:
hostname -fExpected output:
panel.example.comCreate an A record for panel.example.com pointing to your VPS public IP at your DNS provider. Wait for it to propagate (usually under 5 minutes) before continuing:
dig +short panel.example.comThe output should match your VPS IP.
Step 3: Download the Virtualmin Install Script
Virtualmin ships an official installer that configures the apt repositories, installs every stack component, seeds sane default configs, and runs the initial integration checks. Grab it directly from the Virtualmin software host:
wget https://software.virtualmin.com/gpl/scripts/install.shExpected output:
--2026-04-16 10:00:00-- https://software.virtualmin.com/gpl/scripts/install.sh Resolving software.virtualmin.com (software.virtualmin.com)... 208.85.0.26 Connecting to software.virtualmin.com (software.virtualmin.com)|208.85.0.26|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 52341 (51K) [application/x-sh] Saving to: 'install.sh'install.sh 100%[=================================>] 51.11K --.-KB/s in 0.05s
2026-04-16 10:00:00 (1.02 MB/s) - 'install.sh' saved [52341/52341]
Make the script executable:
chmod +x install.shOptionally, inspect it before running — it is a readable shell script:
less install.shStep 4: Run the Installer as Root
Virtualmin must be installed as root (not via sudo from a regular user — the installer reconfigures system services that require a direct root login).
./install.shThe installer prints a banner, verifies the OS is supported, checks the FQDN resolves, confirms minimum RAM, and asks for confirmation:
Welcome to the Virtualmin GPL installer, version 7.x.xThe installation is quite stable and busy working servers are rarely, if ever, damaged by the installation. That said, please DO NOT install Virtualmin on a production system.
This script is not intended to update your system! It must be run on a freshly installed supported OS.
The systems currently supported by install.sh are:
Ubuntu 24.04 LTS on x86_64
If your OS/version/arch is not listed above, this script will fail.
Continue? (y/n)
Type y and press Enter. The installer will:
/etc/apt/sources.list.d/virtualmin.listapt update against the new repovirtualmin config-system to wire everything togetherTotal runtime is typically 8-15 minutes depending on bandwidth and CPU. When it finishes you'll see:
[SUCCESS] Installation Complete!
[SUCCESS] If there were no errors above, Virtualmin should be ready
[SUCCESS] to use at https://panel.example.com:10000 (or https://<ip>:10000).Step 5: Access Webmin and Run the Post-Install Wizard
Open a browser and navigate to:
https://panel.example.com:10000Your browser will warn about the self-signed certificate — click through (you'll replace it with Let's Encrypt in a later step). Log in with your server's root credentials. The root password is the same one you use for SSH.
On first login, Virtualmin runs the Post-Installation Configuration Wizard. Walk through each page:
ns1.example.com, ns2.example.com). You'll create DNS glue records at your registrar later.After the wizard, run the configuration check: System Settings → Re-Check Configuration. Fix any red warnings before creating virtual servers. A clean result looks like:
... your system is ready for use by Virtualmin.Step 6: Configure FQDN, DNS, and the Default Template
Virtualmin's default template controls how every new virtual server gets created — which DNS records to generate, default disk/mail quotas, PHP version, and more. Tune it once before creating your first domain.
Navigate: System Settings → Server Templates → Default Settings.
Key fields to review:
- Network → Automatic IP allocation -- Set to No and fill in your VPS public IP. Shared hosting on a single IP is the norm.
- BIND DNS → Primary nameserver -- Your
ns1.example.comrecord. - BIND DNS → Additional nameservers --
ns2.example.com. - BIND DNS → Master zone records -- Leave at defaults unless you have a reason to customize.
- Administration user → Quota for primary user -- Default
Unlimited; set per-account limits via plans instead. - Plan / Limits → Apache website -- Enabled.
- Plan / Limits → MySQL database -- Enabled.
- Plan / Limits → DNS domain -- Enabled.
- Plan / Limits → Mail for domain -- Enabled.
Also visit System Settings → Features and Plugins and disable anything you don't need (e.g., FrontPage, AWstats) to reduce provisioning time per domain.
Step 7: Create Your First Virtual Server (Domain)
Navigate: Virtualmin → Create Virtual Server.
Fill in:
- Domain name --
yourdomain.com - Description -- Free-text label
- Administration password -- Auto-generate or set one
- Administration username -- Defaults to a sanitized form of the domain
- Server configuration template -- Default Settings
- Account plan -- Default Plan
- Apache website
- SSL website
- DNS domain
- Mail for domain
- MySQL database
- Log file rotation
- Spam filtering
- Virus filtering
yourdomain/home/yourdomain with Apache virtual host docroot at public_html/yourdomain.com with A/MX/NS records[email protected] in Postfix + DovecotExpected final output:
... Creation of virtual server yourdomain.com completePoint yourdomain.com at your VPS IP (A record for @ and www), then load http://yourdomain.com — you'll see the default Virtualmin placeholder page.
Step 8: Add FTP Users, Databases, and Mailboxes
Switch into the domain's context from the top-left dropdown: Virtualmin → yourdomain.com.
Additional FTP / SFTP users
Edit Users → Add a user to this server lets you create extra logins with shell access (SFTP) or sandboxed FTP-only access. Set the Quota column to cap their disk use.
Databases
Edit Databases shows MySQL/MariaDB databases attached to the virtual server. Click Create a new database for each app that needs its own schema (WordPress, Nextcloud, etc.). See the companion guide on installing MariaDB standalone for deeper database tuning — Virtualmin drives the same engine.
Mailboxes
Edit Mail and FTP Users → Add a user to this server creates POP/IMAP mailboxes. Each mailbox gets:
- A Unix account (
user.yourdomain) so webmail and SMTP auth share the same credential store - A Maildir at
/home/yourdomain/homes/user/Maildir - An automatic Dovecot + Postfix entry
https://yourdomain.com/usermin (if enabled) or via any IMAP client (mail.yourdomain.com, ports 993 IMAPS / 465 SMTPS).SpamAssassin per-mailbox tuning
Mail and FTP Users → Spam and Virus Scanning exposes SpamAssassin's score threshold and action (discard vs. deliver to Junk) per mailbox. Defaults are sensible; only tune if users report too much or too little filtering. For a deeper mail infrastructure walkthrough see the related guide on Mailu's standalone stack — Virtualmin uses the same underlying Postfix + Dovecot components.
Step 9: Enable Let's Encrypt SSL
Virtualmin ships a built-in Let's Encrypt client that renews automatically via cron. Issuing a cert takes one click per domain.
In the domain's context: Virtualmin → Server Configuration → SSL Certificate → Let's Encrypt tab.
Settings:
- Domain names for certificate -- Domains associated with this server. This issues a SAN cert covering
yourdomain.com,www.yourdomain.com,mail.yourdomain.com, and the panel subdomain. - Months between automatic renewal --
2(Let's Encrypt certs are 90 days; renewing every 60 leaves headroom).
Expected output:
Requesting a certificate for yourdomain.com, www.yourdomain.com, mail.yourdomain.com from Let's Encrypt ..
... certificate successfully received.
Copying new certificate to webserver ..
... done
Copying new certificate to Dovecot ..
... done
Copying new certificate to Postfix ..
... doneThe cert is installed for Apache, Dovecot, and Postfix automatically. You can also issue a cert for Webmin itself at Webmin → Webmin Configuration → SSL Encryption → Let's Encrypt, pointing at your panel FQDN — that replaces the self-signed cert on port 10000.
For Apache-specific SSL troubleshooting see the companion Apache install guide.
Step 10: Configure PHP Versions and PHP-FPM
Virtualmin lets each domain run a different PHP version via PHP-FPM. That's essential when hosting a mix of legacy sites (PHP 7.4) alongside modern apps (PHP 8.3).
Install additional PHP versions
The installer sets up whatever the distro provides (PHP 8.3 on Ubuntu 24.04). Add more via Ondřej Surý's PPA:
apt install -y software-properties-common
add-apt-repository -y ppa:ondrej/php
apt update
apt install -y php7.4-fpm php7.4-mysql php7.4-gd php7.4-curl php7.4-xml php7.4-mbstring \
php8.1-fpm php8.1-mysql php8.1-gd php8.1-curl php8.1-xml php8.1-mbstring \
php8.2-fpm php8.2-mysql php8.2-gd php8.2-curl php8.2-xml php8.2-mbstringThen in Virtualmin: System Settings → Re-Check Configuration — Virtualmin detects every /usr/bin/phpX.Y binary and registers them as selectable versions.
Switch a virtual server's PHP version
In the domain's context: Server Configuration → PHP Versions. The Execution mode dropdown offers:
- FPM (recommended) — fastest, isolates each domain into its own pool
- fcgid — legacy fallback
- mod_php — deprecated, avoid
Virtualmin generates a dedicated PHP-FPM pool at /etc/phpX.Y/fpm/pool.d/yourdomain.conf with a unique socket, drops an Apache SetHandler directive into the vhost, and reloads both services.
Verify:
curl -sI https://yourdomain.com | grep -i phpExpected output:
X-Powered-By: PHP/8.2.xStep 11: Install WordPress with Installable Scripts
Virtualmin's Installable Scripts feature bundles one-click installers for WordPress, Joomla, phpBB, Roundcube, and dozens more — all free in the GPL edition.
In the domain's context: Install Scripts.
Pick WordPress from the list. Fill in:
- Install options → Install directory --
At top level(install at/) or a subdirectory - Database for script -- Create a new database
- Database username / password -- Auto-generated
Virtualmin downloads the latest WordPress release, extracts it to public_html, creates the database, writes wp-config.php with the correct credentials, and prints the admin URL:
Successfully installed WordPress version 6.x at https://yourdomain.com/Finish the WordPress 5-minute install in your browser as usual. Updates are handled by WordPress's built-in updater — Virtualmin doesn't lock it down.
For a standalone WordPress walkthrough (useful when tuning a single high-traffic site outside the shared-hosting model) see the WordPress install guide.
Step 12: Harden with Firewall and Fail2ban
A fresh Virtualmin host exposes SSH, Webmin, mail, and HTTP to the public internet. Harden it before handing mailboxes to customers.
UFW firewall
Virtualmin can drive UFW for you: Webmin → Networking → Linux Firewall will detect UFW if installed. Install and enable:
apt install -y ufw
ufw allow 22/tcp
ufw allow 25/tcp
ufw allow 53
ufw allow 80/tcp
ufw allow 110/tcp
ufw allow 143/tcp
ufw allow 443/tcp
ufw allow 465/tcp
ufw allow 587/tcp
ufw allow 993/tcp
ufw allow 995/tcp
ufw allow 10000/tcp
ufw --force enableFail2ban
Virtualmin auto-detects Fail2ban and exposes it under Webmin → Networking → Fail2Ban Intrusion Detector. Install and enable:
apt install -y fail2ban
systemctl enable --now fail2banVirtualmin's installer drops jail rules for Webmin, Dovecot, Postfix, and ProFTPD into /etc/fail2ban/jail.d/. For deeper tuning — custom ban times, email alerts, integration with AbuseIPDB — see the dedicated Fail2ban guide.
Restrict Webmin access
If only you log into the panel, lock port 10000 to your home/office IP:
ufw delete allow 10000/tcp
ufw allow from 203.0.113.50 to any port 10000 proto tcpStep 13: Schedule Backups to Remote Storage
Virtualmin includes a full-featured backup engine — per-domain, scheduled, incremental, encrypted, streaming directly to remote destinations without staging to local disk.
Navigate: Backup and Restore → Scheduled Backups → Add a new backup schedule.
Settings:
- Features to backup -- All virtual servers (or select specific ones)
- Backup destination -- One or more of:
[email protected]:/backups/virtualmin
- Amazon S3 -- bucket + access key
- Backblaze B2, Google Cloud Storage, Dropbox, WebDAV — all built in
- Local file -- /var/backups/virtualmin (mount a separate disk for this)
- Backup format -- Separate files per virtual server (easier selective restore)
- Schedule -- Enabled, cron-style (e.g., daily at 03:00)
- Backup encryption -- GPG key of your choice for at-rest encryption on remote storage
- Send email when backup completes -- Your admin address, Only on error
- Purge old backups -- Retain last 7 daily + last 4 weekly
Restoring is the inverse: Backup and Restore → Restore Backup, pick a source, tick which features to restore. Virtualmin will recreate users, databases, DNS, and files.
Cloning and Migrating Virtual Servers
Two common operations Virtualmin makes painless:
Clone a virtual server
Virtualmin → Server Configuration → Clone Virtual Server. Specify the new domain name; Virtualmin copies files, database, mailboxes, and DNS, then rewrites wp-config.php, config DB hosts, and similar references to the new name. Great for staging copies.
Migrate from cPanel, Plesk, or DirectAdmin
Virtualmin → Add Servers → Migrate Virtual Server. Upload a cPanel .tar.gz account backup (or Plesk .tar), and Virtualmin unpacks and remaps it into a new virtual server — Apache vhost, MySQL dump, mail store, DNS zone, and email forwarders are all translated. Works for the vast majority of accounts; a small percentage of exotic configs need manual cleanup afterwards.
Keeping Webmin and Virtualmin Updated
Updates arrive through two channels.
apt (stack components)
Apache, Postfix, MariaDB, PHP, BIND, ClamAV, and Webmin/Virtualmin itself all update via the normal Ubuntu + Virtualmin repositories:
apt update && apt upgrade -yThe Virtualmin repo was added automatically by the installer — check with:
cat /etc/apt/sources.list.d/virtualmin.listWebmin in-UI upgrade
Webmin → Webmin Configuration → Upgrade Webmin fetches the latest Webmin package and installs it without an apt cycle. Useful between distro-package refreshes.
Virtualmin → System Settings → Check for Package Updates surfaces pending updates for every component in one table, with a single Update Selected Packages button.
Schedule an automatic weekly check via Webmin → Webmin Configuration → Upgrade Webmin → Scheduled updating so you're notified the moment a security fix lands.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
Cannot reach https://server:10000 | Port 10000 blocked by firewall or cloud-provider network ACL | Verify UFW: ufw status \</td><td>grep 10000<code>. Check provider firewall dashboard. Confirm Webmin is listening: </code>ss -tlnp \</td><td>grep 10000. |
install.sh aborts: "Your system hostname is not resolvable" | FQDN not set or DNS A record missing | Set FQDN: hostnamectl set-hostname panel.example.com. Add to /etc/hosts. Create A record at registrar. |
| Re-Check Configuration fails with "BIND not running" | BIND failed to start (common on 1 GB RAM VPS) | systemctl status bind9 and journalctl -u bind9 -n 50. Usually fixed by adding swap or restarting: systemctl restart bind9. |
| Let's Encrypt: "too many certificates already issued for exact set of domains" | Hit Let's Encrypt weekly rate limit (5 certs/domain/week) | Wait 7 days, or use --staging for testing. Consolidate multiple certificate requests into one SAN cert. |
| Mail sent but bounces with "host rejected" | Missing SPF/DKIM/reverse DNS records | Virtualmin auto-generates SPF + DKIM in the BIND zone. Verify with dig TXT yourdomain.com. Ask your VPS provider to set rDNS (PTR) for your IP. |
| Can't log into Webmin after password change | Root password changed but Webmin cache stale | Reset via CLI: /usr/share/webmin/changepass.pl /etc/webmin root newpassword. |
| WordPress installable script fails mid-install | PHP version or extension missing | Check Server Configuration → PHP Versions is set to FPM 8.1+. Install missing extensions: apt install php8.2-gd php8.2-mbstring php8.2-xml. |
Error: Insufficient memory during install | <2 GB RAM or no swap | Add swap: fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile && echo "/swapfile none swap sw 0 0" >> /etc/fstab. |
| SpamAssassin consuming 100% CPU | Every message rescanned by spamd with cold cache | Switch wizard answer to Server mode so the daemon stays warm. Check systemctl status spamassassin. |
| Port 25 outbound blocked | Many cloud providers block egress SMTP | Open a support ticket with your provider to unblock, or relay through a smart-host (AWS SES, SendGrid, Postmark) via Webmin → Postfix → General Options → Send outgoing mail via host. |
Viewing logs
Virtualmin drives standard services, so standard logs apply:
# Webmin itself
tail -f /var/webmin/miniserv.errorApache
tail -f /var/log/apache2/error.logPostfix
journalctl -u postfix -fInstaller output (if the install.sh run errored)
tail -f /root/virtualmin-install.logFAQ
Is Virtualmin GPL really fully free, or is this a trial?
Virtualmin GPL is free forever, with no trial timer, no account limits, and no feature unlocks behind a paywall on a single server. The Professional edition adds multi-server clustering, a reseller/billing layer, the cloud-integrated DNS provider module, and official commercial support — but none of the GPL features disappear or degrade over time. Virtualmin's revenue model is selling Pro to hosts who want clustering and support, while the GPL version stays Apache-licensed and open.
Can I host unlimited domains on a single Virtualmin GPL server?
Yes. The GPL edition has no domain count limit, no mailbox limit, no database limit — only your hardware's limits apply. In practice a 2 GB VPS comfortably hosts 10-20 low-traffic domains, a 4 GB VPS handles 30-50, and an 8 GB VPS supports 100+ if the sites are mostly static or lightly used. Heavy PHP workloads (WordPress + WooCommerce with thousands of daily visitors) are the main driver of per-domain RAM use, not Virtualmin itself.
How does Virtualmin compare to cPanel, Plesk, and CyberPanel?
Virtualmin is the most mature open-source option, uses standard Ubuntu packages throughout (Apache, Postfix, BIND, MariaDB), and has no licensing cost for single-server deployments. Best for: solo developers, small agencies, anyone who values the underlying stack being "normal Ubuntu" rather than a custom fork.
cPanel is the industry standard for traditional shared hosting, with the largest third-party integration ecosystem (billing systems, migration tools, staff training). Paid, priced per-account, and has switched to per-account pricing that scales aggressively with large hosts. Best for: hosting providers with hundreds of accounts and existing cPanel-trained staff.
Plesk is cPanel's main commercial competitor, strong on Windows Server support and with a slicker UI. Paid, priced per-domain tier. Best for: Windows hosting or agencies that prefer the visual design.
CyberPanel is a newer open-source panel built on OpenLiteSpeed (not Apache). Free, fast, includes Git/Docker integrations. Younger codebase than Virtualmin and smaller community — occasional sharp edges. Best for: teams already committed to LiteSpeed / LSCache workflows.
For most VPS operators the decision is Virtualmin (free, mature, standard stack) vs. CyberPanel (free, fast, LiteSpeed-native). Stick with Virtualmin if reliability and package stability matter more than raw PHP benchmarks.
Does Virtualmin support Nginx instead of Apache?
Yes. The installer has an --bundle LAMP (default, Apache) and --bundle LEMP (Nginx) mode. Run ./install.sh --bundle LEMP on a fresh system to get the Nginx-based stack. Note the Nginx path receives less testing than the Apache path — if you're new to Virtualmin, the Apache default is the smoother road. For a standalone Nginx setup outside Virtualmin see the Nginx install guide.
Can I use Virtualmin as a DNS-only or mail-only server?
Yes — features are toggleable per virtual server and globally. System Settings → Features and Plugins lets you disable, for example, Apache and MySQL to run a DNS-only or mail-only box. Common patterns: a small VPS running only BIND DNS as your secondary nameserver, or a mail-only box with Postfix + Dovecot + SpamAssassin but no web serving. For a lightweight Postfix-centric deployment see the Mailu install guide.
How do I migrate my existing cPanel accounts to Virtualmin?
Download each account's full backup from cPanel as a .tar.gz, upload it to your Virtualmin server (SFTP to /root/migrations/), then use Virtualmin → Add Servers → Migrate Virtual Server. Pick cPanel as the source format, browse to the file, and Virtualmin unpacks the files, database, mail store, DNS zone, and email accounts into a fresh virtual server. Most accounts migrate cleanly; plan for 10-15 minutes of per-account cleanup (testing contact forms, re-issuing SSL, double-checking cron jobs). See the WHMCS-to-DM migration playbook for database-layer details that often apply during bulk migrations.
Next Steps
With Virtualmin running, here's what to tackle next:
- Audit your mail deliverability -- After pointing real MX records at your server, run a test through mail-tester.com to verify SPF, DKIM, DMARC, and rDNS are aligned. Fix any red items before inviting real users. SpamAssassin + Postfix do the heavy lifting; rDNS is on your VPS provider.
- Set up remote off-box monitoring -- Virtualmin monitors its own services, but you want external visibility. Deploy Uptime Kuma on a separate small VPS and watch ports 80, 443, 25, 993, and 10000.
- Enable two-factor authentication for Webmin -- Webmin → Webmin Users → Two-Factor Authentication, TOTP via Google Authenticator or Authy. Mandatory for any server exposed to the public internet.
- Automate provisioning with the CLI -- Every UI action has a
virtualmincommand equivalent. Script bulk account creation:virtualmin create-domain --domain example.com --pass x --desc "Client A" --plan Default. Ideal for Ansible roles when you're spinning up identical boxes for each client.
- Add a staging virtual server per site -- Use the clone feature to maintain
staging.yourdomain.comalongside production, so you can test WordPress plugin updates, PHP version bumps, and Apache config changes safely.
- Expand the stack with standalone services -- Keep Virtualmin for shared hosting, but run heavy workloads on dedicated hosts. See the standalone MariaDB, Apache, and Fail2ban guides for deeper tuning than the Virtualmin UI exposes.
Launch a Virtualmin-ready VPS in 60 Seconds>
Our CloudCore Professional plan gives you a clean Ubuntu 24.04 image with the exact spec Virtualmin wants for a comfortable shared-hosting setup:>
- 6 vCPU cores and 12 GB RAM (enough for ClamAV + SpamAssassin resident)
- 100 GB NVMe SSD for mailbox + backup headroom
- Unmetered bandwidth
- Full root SSH access for the install.sh installer
- Reverse DNS configurable from the control panel (essential for mail deliverability)>
Deploy a CloudCore Professional VPS Now -- EUR 19.99/month, cancel any time.