Application Stacks Azure

Hestia Control Panel on Ubuntu 24.04 on Azure User Guide

| Product: Hestia Control Panel on Ubuntu 24.04 LTS on Azure

Overview

Hestia Control Panel is an open source web hosting control panel. It turns a single Linux server into a manageable hosting platform: you add a domain in the browser and Hestia provisions the nginx and Apache virtual hosts, the PHP-FPM pool, the document root and the TLS certificate for it, without you editing any web server configuration by hand. It also manages hosting users, databases, cron jobs and backups, and exposes the same operations through a command line toolset and a REST API.

The cloudimg image installs Hestia Control Panel 1.9.7 from the official upstream installer, together with the web stack it manages: nginx as the public front end, Apache 2.4 with PHP-FPM as the application backend, and MariaDB for databases. A unique administrator password, a unique MariaDB root password and a unique self signed TLS certificate are generated on the first boot of every VM, so no image wide default login exists. Backed by 24/7 cloudimg support.

This image is deliberately a WEB hosting appliance, not a mail or DNS server. The mail stack (Exim, Dovecot), the DNS server (BIND), the FTP servers (vsftpd, ProFTPD), ClamAV and SpamAssassin are all left out. That is a security decision as much as a sizing one: it removes any possibility of shipping an open mail relay or an open recursive DNS resolver, which are the two most damaging misconfigurations a public cloud image can carry. If you need mail or DNS hosting, run them on dedicated infrastructure.

Hestia has full administrative control of the operating system it runs on. It can create and delete system users, provision databases, edit web server configuration and change the firewall. Treat the panel credentials as root equivalent, and read the security notes in Maintenance before exposing this VM beyond your own management network.

What is included:

  • Hestia Control Panel 1.9.7, installed from the official upstream installer at a pinned commit
  • nginx serving the public web ports 80 and 443, and the panel itself over HTTPS on port 8083
  • Apache 2.4 with PHP-FPM 8.3 as the web application backend
  • MariaDB, bound to 127.0.0.1 so it is never reachable off the VM
  • Hestia's own iptables firewall, default deny on inbound, plus Fail2Ban
  • The REST API enabled but restricted to 127.0.0.1, so it is not reachable from the internet
  • A unique panel password, MariaDB root password and TLS certificate generated on first boot
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet and subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended starting size: a control panel that is actually serving sites runs nginx, Apache, several PHP-FPM pools and MariaDB together, so it needs meaningfully more memory than a single service appliance. Smaller sizes will boot and run the panel, but leave little headroom once you host real traffic.

NSG inbound rules: allow 22/tcp from your management network only, allow 80/tcp and 443/tcp if you intend to serve websites from this server, and restrict 8083/tcp (the Hestia panel) to trusted source IP ranges. Do not leave the panel open to the whole internet, since it has full control of the box.

Step 1 - Deploy from the Azure Marketplace

In the Azure portal, search the Marketplace for Hestia Control Panel on Ubuntu 24.04 LTS (publisher: cloudimg), then select Create. Choose your subscription, resource group and region, set the VM size to Standard_B2ms, and select SSH public key as the authentication type with username azureuser. On the Networking tab, attach an NSG with the inbound rules described in Prerequisites.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group my-resource-group \
  --name hestiacp-vm \
  --image cloudimg:hestiacp-ubuntu-24-04:default:latest \
  --size Standard_B2ms \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open only the ports you need. Restrict the panel port to your own address rather than leaving it world reachable:

az vm open-port --resource-group my-resource-group --name hestiacp-vm --port 80 --priority 1010
az vm open-port --resource-group my-resource-group --name hestiacp-vm --port 443 --priority 1020

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the hosting stack is running

Hestia runs as its own service alongside the stack it manages. All five units should report active:

systemctl is-active hestia nginx apache2 mariadb php8.3-fpm
active
active
active
active
active

Ask Hestia itself what it is running:

sudo /usr/local/hestia/bin/v-list-sys-info
HOSTNAME                        OS      VER    ARCH    HESTIA  RELEASE  UPTIME  LA
--------                        --      ---    ----    ------  -------  ------  --
hestia-52-188-116-173.cloudimg.local  Ubuntu  24.04  x86_64  1.9.7   release  46    0.00 / 0.08 / 0.35

Hestia and the managed web stack reporting active, with the panel version from v-list-sys-info

The hostname is derived from your VM's own public address on first boot, so it will differ from the example above.

Step 5 - Retrieve your panel password

Every VM generates its own administrator password on first boot and writes it to a root only file:

sudo cat /stage/scripts/hestiacp-credentials.log
# HestiaCP — Per-VM Credentials (cloudimg)
# Generated: Sat Jul 18 23:53:26 UTC 2026
HESTIA_URL=https://52.188.116.173:8083/
HESTIA_ADMIN_USER=admin
HESTIA_ADMIN_PASSWORD=********************
HESTIA_HOSTNAME=hestia-52-188-116-173.cloudimg.local
HESTIA_MYSQL_ROOT_PASSWORD=********************

The file is mode 0600 and owned by root, so only root can read it:

stat -c '%a %U:%G %n' /stage/scripts/hestiacp-credentials.log
600 root:root /stage/scripts/hestiacp-credentials.log

The per-VM credentials file with passwords masked, showing 0600 root:root permissions

HESTIA_MYSQL_ROOT_PASSWORD is the MariaDB root credential that Hestia itself uses to provision databases. It is regenerated per VM as well, so no two cloudimg VMs share a database root password.

Step 6 - Review what is actually reachable

The image ships Hestia's own firewall with a default deny inbound policy:

sudo iptables -L INPUT -n | head -1
Chain INPUT (policy DROP)

Only four inbound services are accepted - ICMP, the panel, the web ports and SSH:

sudo /usr/local/hestia/bin/v-list-firewall plain | awk -F'\t' '{print $1, $2, $3, $5, $6}'
1 ACCEPT ICMP 0.0.0.0/0 PING
2 ACCEPT TCP 0.0.0.0/0 HESTIA
9 ACCEPT TCP 0.0.0.0/0 WEB
10 ACCEPT TCP 0.0.0.0/0 SSH

The host firewall showing a default DROP policy and the four accepted inbound services

Apache also listens on 8080 and 8443 as nginx's backend. Those are Hestia's internal plumbing, they are not in the firewall accept list, and they are not reachable from outside the VM. MariaDB is bound to 127.0.0.1 and is never exposed.

Step 7 - Verify authentication from the command line

Hestia's REST API is enabled but restricted to 127.0.0.1, so this call only works from on the VM itself. A return code of 0 means the per-VM password authenticated successfully:

PASS=$(sudo grep '^HESTIA_ADMIN_PASSWORD=' /stage/scripts/hestiacp-credentials.log | cut -d= -f2-)
curl -sk -m 20 -X POST https://127.0.0.1:8083/api/ \
  --data-urlencode 'user=admin' \
  --data-urlencode "password=${PASS}" \
  --data-urlencode 'returncode=yes' \
  --data-urlencode 'cmd=v-list-user' \
  --data-urlencode 'arg1=admin' \
  --data-urlencode 'arg2=json'
0

A wrong password is rejected with return code 9, and a request with no credentials at all is refused outright:

curl -sk -m 20 -X POST https://127.0.0.1:8083/api/ \
  --data-urlencode 'user=admin' \
  --data-urlencode 'password=not-the-password' \
  --data-urlencode 'returncode=yes' \
  --data-urlencode 'cmd=v-list-user' \
  --data-urlencode 'arg1=admin' \
  --data-urlencode 'arg2=json'
9

An authenticated API round-trip returning 0, with wrong-password and no-credential attempts both refused

The API roles that ship with the panel can be listed with:

sudo /usr/local/hestia/bin/v-list-apis

To use the API from another machine, add that machine's address explicitly with sudo /usr/local/hestia/bin/v-add-sys-api-ip <ip>, and treat that access as root equivalent.

Step 8 - Sign in to the panel

Browse to the URL from your credentials file, https://<vm-public-ip>:8083/. The certificate is self signed and generated for this VM, so your browser will warn on first visit. Sign in with username admin and the password from Step 5. Hestia asks for the username first, then the password on a second screen.

The Hestia Control Panel sign-in page served over HTTPS on port 8083

Step 9 - The panel overview

After signing in you land on the user list, with counters across the top for users, web domains, databases, cron jobs and backups. A freshly deployed VM has exactly one account, admin, and no websites or databases yet.

The Hestia user list after signing in, showing the single admin account on a fresh VM

Step 10 - Add your first website

Select WEB in the top navigation, then Add Web Domain. Enter the domain name you want to host and select Save. Hestia creates the nginx virtual host, the Apache backend virtual host, the PHP-FPM pool and the document root under /home/admin/web/<domain>/public_html/ in one step.

The Hestia Web domains view, where hosted sites are added and managed

Point your domain's DNS A record at the VM's public IP address, then use Hestia's built in Let's Encrypt support on the domain's settings page to replace the self signed certificate with a trusted one. Let's Encrypt validation requires the domain to already resolve to this VM and port 80 to be reachable.

You can do the same from the command line:

sudo /usr/local/hestia/bin/v-list-web-domains admin plain

Step 11 - Review the managed services

The Server view lists every service Hestia manages on this VM, with its state and memory use. This is where you restart nginx, Apache, PHP-FPM or MariaDB, and where you configure the panel itself.

The Hestia server configuration view listing the managed services and their state

Maintenance

Restrict the panel port. Port 8083 gives full administrative control of this VM. Restrict it to trusted source IP ranges in your NSG. If you can, reach it over a VPN or a bastion rather than exposing it to the internet at all.

Change the administrator password. The generated password is unique per VM, but you should still replace it with one held in your own password manager, from User then admin then Edit, or from the command line:

sudo /usr/local/hestia/bin/v-list-users plain | awk '{print $1}'

The REST API is loopback only by default. Nothing outside the VM can use it. If you need remote API access, add each client address explicitly with v-add-sys-api-ip <ip> and treat those keys as root equivalent.

Hestia updates itself. Automatic updates are enabled, which is the upstream default and the right choice for an internet facing control panel, since panel vulnerabilities are actively exploited. The image ships 1.9.7 and will move forward as upstream publishes releases. If your change control requires pinning, disable it with v-change-sys-hestia-autoupdate disable, and take responsibility for applying updates yourself.

Fail2Ban will lock you out if you get it wrong repeatedly. The image ships Fail2Ban with jails for SSH, the panel and phpMyAdmin, and it bans the offending source IP after repeated failures. That is deliberate, but it applies to you too. If you lock yourself out, connect from another address or via the Azure serial console and clear the ban:

sudo fail2ban-client status ssh-iptables

Then release a specific address with sudo fail2ban-client set ssh-iptables unbanip <ip>.

Operating system updates are handled by Ubuntu's unattended-upgrades, which is enabled in the image.

Backups. Hestia can back up hosting accounts to /backup on the same disk, which does not protect you from losing the VM. Configure Azure Backup on the VM, or set a remote backup destination in Hestia, before you host anything you care about.

Mail and DNS are not installed. Do not expect this VM to send mail for hosted sites. Use an external mail provider or a dedicated mail server.

Support

cloudimg images are backed by 24/7 support. Contact support@cloudimg.co.uk with the offer name, your VM size and region, and any relevant output from the commands in this guide.