Virtualmin
Overview
Virtualmin GPL is an open-source web hosting control panel built on Webmin. It turns a single Linux server into a multi-tenant hosting platform. Each website you add becomes a virtual server, and Virtualmin provisions everything that site needs in one step: an Apache virtual host, a dedicated Unix user and home directory, a DNS zone, mailboxes, a database and FTP access.
This SecureAnyCloud image installs Virtualmin GPL through the official upstream installer, pinned to the GPL edition, together with the hosting stack it manages. You can run dozens of domains without hand-editing Apache, BIND, Postfix and MariaDB configuration separately.
Virtualmin has full administrative control of the operating system it runs on. It can create and delete system users, edit DNS zones, install packages, change the firewall, and read and write almost any file on the server. Treat the panel credentials as root-equivalent, and read the security notes in Maintenance before you expose this VM beyond your own management network.
What you get:
- Virtualmin GPL installed through the official upstream installer, explicitly pinned to the GPL edition
- Webmin's own web server (miniserv) serving the Virtualmin console over HTTPS directly on port
10000, with Webmin's session login as the only gate in front of it - The full hosting stack the panel manages: Apache, MariaDB, PHP, Postfix, Dovecot and BIND
- Ports
80and443reserved for Apache to serve your hosted websites - A unique administrator password and a unique self-signed TLS certificate, generated on the first boot of every VM
- The panel password recorded in a root-only file (username root)
webmin.serviceplus the Apache, MariaDB, Postfix, Dovecot and BIND units, enabled and active- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B4ms (4 vCPU / 16 GiB RAM) is the recommended starting size. Virtualmin runs a web server, a database, a mail stack and a DNS server together, so it needs more memory than a single-service appliance.
Configure the network security group (NSG) for inbound traffic as follows:
- Allow
22/tcpfrom your management network only. - Allow
80/tcpand443/tcpif you intend to serve websites from this server. - Restrict
10000/tcp(the Virtualmin panel) to trusted source IP ranges. Do not leave it open to the whole internet, because the panel has full control of the server.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Virtualmin by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key.
Under Inbound port rules, allow SSH (22), HTTP (80) and HTTPS (443). Then add a custom rule for TCP 10000 restricted to your own IP range. Select Review + create, then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name virtualmin \
--image <marketplace-image-urn> \
--size Standard_B4ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name virtualmin --port 80 --priority 1010
az vm open-port --resource-group <your-rg> --name virtualmin --port 443 --priority 1015
az vm open-port --resource-group <your-rg> --name virtualmin --port 10000 --priority 1020Restrict the port 10000 NSG rule to your own management IP range. Do not leave it open to *.
Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the hosting stack is running
Virtualmin is several services working together. Confirm that they are all active:
systemctl is-active webmin.service apache2.service mariadb.service postfix.service dovecot.service named.serviceEvery line should read active. Then confirm that the panel listens on port 10000:
sudo ss -tln | grep ':10000'Step 5 - Retrieve your panel password
Each VM generates a unique panel password on first boot and writes it to a root-only file. No password is baked into the image. Read the file with sudo:
sudo cat /root/virtualmin-credentials.txtTo confirm that the installed edition is GPL, with no server limit, run:
sudo virtualmin license-infoStep 6 - Confirm the panel is serving over TLS
curl -sk -o /dev/null -w 'HTTP %{http_code}\n' https://127.0.0.1:10000/session_login.cgiHTTP 200 confirms that the panel is serving its login page. A freshly deployed image hosts no websites until you create one:
sudo virtualmin list-domains --name-onlyStep 7 - Verify authentication from the command line
Before you open the panel in a browser, confirm that the generated password authenticates and that a wrong password does not. Virtualmin's login is a form POST to session_login.cgi. It requires a cookie from an initial unauthenticated request, so the check first primes a cookie jar:
login(){ jar=$(mktemp); curl -sk -o /dev/null -c "$jar" https://127.0.0.1:10000/session_login.cgi; s=$(curl -sk -o /dev/null -b "$jar" -c "$jar" -w '%{http_code}' --data-urlencode action=login --data-urlencode user=root --data-urlencode "pass=$1" --data-urlencode page=/ https://127.0.0.1:10000/session_login.cgi); rm -f "$jar"; echo "$s"; }
PW=$(sudo grep '^VIRTUALMIN_PASSWORD=' /root/virtualmin-credentials.txt | cut -d= -f2-) login "$PW" login "wrong-pw-xyz"The correct password returns 302, which means you are authenticated and have a fresh session cookie. The wrong password returns 200: the login form is redisplayed and no session is issued.
Step 8 - Sign in to the panel
Browse to https://<vm-public-ip>:10000/ and sign in with username root and the password from Step 5.
The appliance ships a self-signed certificate generated for this VM, so your browser shows a warning the first time. Accept it, or install a trusted certificate as described in Maintenance.
Step 9 - The Virtualmin dashboard
After you sign in, you land on the Virtualmin dashboard. It lists your virtual servers and summarizes the health of the server behind them.
Step 10 - Create your first virtual server
Choose Create Virtual Server, enter the domain name you want to host, and set an administration password. Then choose the features it should have: website, DNS zone, mailboxes, database and so on. Virtualmin provisions all of them together.
The same operation is available from the command line, which suits scripted bulk provisioning:
sudo virtualmin create-domain \
--domain example.com \
--pass <a-strong-password> \
--unix --dir --web --dns --mail --logrotateStep 11 - Verify a virtual server from the command line
Once a virtual server exists, list it and show what Virtualmin provisioned for it:
sudo virtualmin list-domains --name-only sudo virtualmin list-domains --domain example.com --multilineEach virtual server gets its own Unix user and home directory (with a public_html web root) and its own Apache virtual host. If you enabled them, it also gets its own DNS zone and mailboxes. To remove a virtual server and everything it owns, run:
sudo virtualmin delete-domain --domain example.comStep 12 - System information
Open Webmin's System Information page to see the server's load, memory, disk and package status beneath the panel.
Maintenance
Restrict access to the panel. Port 10000 gives complete control of this server. Scope its NSG rule to trusted management IP ranges, and never expose it to 0.0.0.0/0.
Replace the self-signed certificate. The appliance generates a self-signed certificate for this VM on first boot. For production, install a trusted certificate from within the panel at Webmin -> Webmin Configuration -> SSL Encryption. You can also use Virtualmin's built-in Let's Encrypt support, which is fully available in the GPL edition.
The server hostname is fixed by design. Virtualmin writes the appliance hostname into Apache, Postfix and BIND configuration at install time, so the image keeps its hostname rather than adopting the Azure VM name. To rename the server, go to Webmin -> Networking -> Network Configuration -> Hostname and DNS Client. Then run Virtualmin -> System Settings -> Re-Check Configuration.
The post-installation wizard. Virtualmin normally intercepts the first administrator login with a multi-step post-installation wizard, and the panel is not usable until the wizard is completed. This image ships with the wizard already completed using Virtualmin's own default settings, so you land straight on the dashboard. To revisit those choices, run the wizard at any time from Virtualmin -> System Settings -> Re-run post-installation wizard. The choices cover preloading libraries for lower memory use, spam and virus scanning, database passwords, and DNS behavior.
DNS. Virtualmin can create BIND zones for the domains you host. For those zones to be authoritative on the public internet, point the domain's nameservers at this server and open port 53. If you use an external DNS provider instead, create virtual servers without the DNS feature.
GPL edition and source code. This image ships Virtualmin GPL, which is licensed under the GNU General Public License v3, and Webmin, which is licensed under the BSD 3-Clause License. Their license texts ship on the image under /usr/share/doc. Corresponding source is available from the upstream projects at github.com/virtualmin/virtualmin-gpl and github.com/webmin/webmin. Virtualmin Professional is a separate commercial product and is not included.
Updates. The image is patched at build time and keeps Ubuntu's unattended security updates enabled. Virtualmin and Webmin update through the Virtualmin package repositories. Use the panel's System Information -> Package Updates page or apt.
Support
SecureAnyCloud images are backed by 24/7 support. Contact sales@secureanycloud.com and include your Azure subscription ID and the VM name.
Deploy on Azure
Launch Virtualmin GPL on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Virtualmin GPL is a free, open-source web hosting control panel built on Webmin. From one point-and-click panel, it provisions and manages many websites on a single server. It wires together the Apache web server, MariaDB databases, Postfix and Dovecot email, BIND DNS and per-site users for each virtual server (hosting account) you create.
This SecureAnyCloud Amazon Machine Image (AMI) delivers the complete hosting stack, fully installed and configured on Ubuntu 24.04, so a working control panel is running within minutes of launch. Webmin's own web server (miniserv) serves the panel over HTTPS on port 10000, and Apache owns ports 80 and 443 for the websites you host. The installed edition is the open-source GPL edition (GPL-3.0). Core hosting management is fully functional with no per-domain licensing.
This guide covers connecting to your instance, retrieving the per-instance administrator password, signing in to the panel, creating your first virtual server, scoping the admin port, installing a real TLS certificate and renaming the server.
The panel is root-equivalent. The Virtualmin admin has full control of the server and provisions system users, mailboxes and DNS zones. Treat its password as root-equivalent and restrict the admin port (10000) to trusted source IPs. See Securing the admin port below.
Architecture at a glance
Component Detail
Control panel Virtualmin GPL 8.1.0 on Webmin 2.652, served on port 10000 over HTTPS
Web server Apache (apache2) on ports 80 / 443, one virtual host per hosted site
Database MariaDB, managed per hosted site
Email Postfix (SMTP) and Dovecot (IMAP/POP3), per hosted domain
DNS BIND (named), one zone per hosted domain
Admin panel URL https://<instance-public-ip>:10000/ (self-signed certificate)
Health endpoint https://127.0.0.1:10000/session_login.cgi (returns the login page)
Virtualmin manages the whole server, so its data (hosted-site home directories, the MariaDB datadir, mail spools and DNS zones) lives on the operating-system disk rather than on a separate volume. Grow the root EBS volume if you host many sites.
Connecting to your instance
Connect over SSH on port 22 as the default login user for your operating-system variant.
OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<instance-public-ip>Replace <instance-public-ip> with the public IPv4 address of your instance, which you can find in the EC2 console. Replace /path/to/your-key.pem with the private key you launched the instance with.
Per-instance credentials
On the first boot of every instance, a one-shot service (virtualmin-firstboot.service) generates an identity that is unique to that instance:
- A fresh self-signed TLS certificate for the panel
- A fresh 24-character administrator password for the Virtualmin
rootpanel user
No default or shared credentials ship in the image, and the operating-system root account stays locked. The panel password is written to a root-only file. Retrieve it over SSH:
cat /root/virtualmin-credentials.txtThe file looks like this (your URL and password will differ):
VIRTUALMIN_URL=https://<instance-public-ip>:10000/ VIRTUALMIN_USERNAME=root VIRTUALMIN_PASSWORD=<set-at-first-boot>Sign in to the panel as user root with the VIRTUALMIN_PASSWORD value.
Signing in to the panel
Browse to https://<instance-public-ip>:10000/. The appliance ships a self-signed certificate, so your browser shows a certificate warning the first time. This is expected, so proceed to the site. To replace the certificate for production, see Installing a real TLS certificate below.
Sign in as root with the password from the credentials file. The dashboard shows the running GPL edition, live CPU, memory and disk usage, and the package status of the server.
Securing the admin port (important)
Port 10000 is the control panel and is root-equivalent, so it must not be open to the whole internet. In your EC2 security group, scope inbound tcp/10000 to the specific source IP addresses your administrators connect from, for example your office or VPN egress. Leave ports 80 and 443 open for the websites you host. Scope SSH (port 22) to trusted sources as well.
Confirm which services are listening on the instance:
ss -tln | grep -E ':(80|443|10000)\b'Creating your first virtual server
A virtual server is one hosted domain with its own website, database, mailboxes, DNS zone and Unix user. In the panel, choose Create Virtual Server, enter the domain name and an administration password. Virtualmin provisions the whole stack for that domain in one step.
The Enabled features section shows everything provisioned for the domain: the Apache website, MariaDB database, DNS zone, mailboxes and spam/virus filtering. The Virtual Servers page lists and manages every hosted domain you create.
You can do the same from the command line. This command lists the hosted domains, which is empty on a fresh instance:
virtualmin list-domains --name-onlyTo create a domain from the shell, replace the domain and choose a strong password:
virtualmin create-domain --domain example.test --pass 'CHANGE-ME' --unix --dir --web --dns --mailManaging the hosting stack
The hosting daemons run as systemd services. Confirm that they are active:
systemctl is-active webmin apache2 mariadb postfix dovecot namedEach service prints active:
active active active active active activeManage any of them with systemctl (for example systemctl restart apache2). The control panel itself is the webmin service.
To confirm that the installed edition is the open-source GPL edition, run:
grep '^SerialNumber=' /etc/virtualmin-licenseSerialNumber=GPLInstalling a real TLS certificate
The panel ships a self-signed certificate. For production, install a trusted certificate:
- For the panel itself: in Webmin, go to Webmin -> Webmin Configuration -> SSL Encryption. Upload a certificate, or request one from Let's Encrypt for a hostname that resolves to this instance.
- For a hosted website: open the virtual server, then go to Server Configuration -> SSL Certificate -> Let's Encrypt and request a certificate for that domain. The domain's DNS must point at this instance first.
Renaming the server
The appliance boots with the hostname virtualmin.secureanycloud.com. Virtualmin baked this name into its Apache, Postfix and BIND configuration at build time, and cloud-init is configured to preserve it. To give the server its own name, rename it from within Virtualmin so that every dependent service is updated together:
- Webmin -> Networking -> Network Configuration -> Hostname and DNS Client: set the new fully qualified hostname.
- Virtualmin -> System Settings -> Re-Check Configuration: this makes Virtualmin re-read the new identity across Apache, Postfix and BIND.
Do not change the hostname with hostnamectl alone. That would put the hosting stack out of sync with the name Virtualmin has recorded.
Support
This AMI includes 24/7 technical support from SecureAnyCloud by email and live chat. We help with deployment, creating and managing virtual servers, DNS and mail configuration, TLS certificate installation, backups and upgrades.
- Email: sales@secureanycloud.com
- Live chat: available 24/7 at secureanycloud.com
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch Virtualmin GPL with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com