Deployment guide

Hestiacp

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. You never edit web server configuration by hand.

Hestia also manages hosting users, databases, cron jobs and backups. It exposes the same operations through a command line toolset and a REST API.

The SecureAnyCloud image installs Hestia Control Panel from the official upstream installer. It is built from 1.9.7 and kept current through Hestia's own update channel, at 1.10.5 in the latest image. The image includes the web stack that Hestia manages: nginx as the public front end, Apache 2.4 with PHP-FPM as the application backend, and MariaDB for databases.

A unique MariaDB root password and a unique self-signed TLS certificate are generated on the first boot of every VM. The panel's admin login ships locked. You activate it yourself with one command over SSH, which generates a password that exists only on your VM. No image-wide default login exists.

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. This 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. Read the security notes in Maintenance before you expose this VM beyond your own management network.

What you get:

  • Hestia Control Panel, installed from the official upstream installer at a pinned commit and updated through Hestia's own release channel
  • 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 MariaDB root password and TLS certificate generated on first boot, and a panel login you activate yourself with sudo hestia-set-admin-password
  • 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_B2ms (2 vCPU / 8 GiB RAM) is the recommended starting size. A control panel that is serving sites runs nginx, Apache, several PHP-FPM pools and MariaDB together, so it needs more memory than a single-service appliance. Smaller sizes boot and run the panel, but leave little headroom once you host real traffic.

Configure the NSG with these 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.
  • Restrict 8083/tcp (the Hestia panel) to trusted source IP ranges. Do not leave the panel open to the whole internet, because it has full control of the VM.

Step 1 - Deploy from the Azure Marketplace

In the Azure portal, search the Marketplace for Hestia Control Panel on Ubuntu 24.04 LTS (publisher: SecureAnyCloud), then select Create.

Choose your subscription, resource group and region. Set the VM size to Standard_B2ms. 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 image terms accept --urn sac1647283583153:hestiacp-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-resource-group \
  --name hestiacp-vm \
  --image sac1647283583153: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. Keep the panel port restricted to your own address rather than reachable from the whole internet:

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.sac.local Ubuntu 24.04 x86_64 1.10.5 release 46 0.00 / 0.08 / 0.35

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

Step 5 - Activate your panel login

The panel's admin account ships locked, so nobody can sign in to a freshly deployed VM until you activate it. If you have not activated it yet, the SSH login message reminds you. Activate it with one command:

sudo hestia-set-admin-password
HestiaCP panel login is active. URL: https://52.188.116.173:8083/ Username: admin Password: **************************************** (also recorded in /stage/scripts/hestiacp-credentials.log, root only)

The password is generated on your VM at that moment and exists nowhere else. To choose your own password instead (at least 12 characters), run sudo hestia-set-admin-password --prompt. Run the command again at any time to reset a forgotten panel password.

The VM's other per-VM details are in a root-only file:

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

Until you activate the login, HESTIA_ADMIN_PASSWORD reads (not set yet - run: sudo hestia-set-admin-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

HESTIA_MYSQL_ROOT_PASSWORD is the MariaDB root credential that Hestia uses to provision databases. It is regenerated per VM too, so no two SecureAnyCloud 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

Apache also listens on 8080 and 8443 as nginx's backend. These ports are internal to Hestia. They are not in the firewall accept list and 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 works only from the VM itself. A return code of 0 means the per-VM password authenticated successfully:

sudo grep '^HESTIA_ADMIN_PASSWORD=' /stage/scripts/hestiacp-credentials.log | cut -d= -f2- | tr -d '\n' | \
  curl -sk -m 20 -X POST https://127.0.0.1:8083/api/ \
  --data-urlencode 'user=admin' \
  --data-urlencode 'password@-' \
  --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

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 warns you on the first visit.

Sign in with username admin and the password you activated in Step 5. Hestia asks for the username first, then the password on a second screen.

Step 9 - Explore the panel overview

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

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. In one step, 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/.

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. Use it to restart nginx, Apache, PHP-FPM or MariaDB, and to configure the panel itself.

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 activated password is unique to your VM, but you may 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. This is the upstream default and the right choice for an internet-facing control panel, since panel vulnerabilities are actively exploited. The image ships a current 1.10 release and moves forward as upstream publishes releases. If your change control requires pinning, disable automatic updates with v-change-sys-hestia-autoupdate disable. You then take responsibility for applying updates yourself.

Fail2Ban bans your address after repeated failures. The image ships Fail2Ban with jails for SSH, the panel and phpMyAdmin. It bans the offending source IP after repeated failures. This is deliberate, but it applies to you too. If you lock yourself out, connect from another address or through 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.

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

ImageMagick and the PHP Imagick extension are not installed. Ubuntu publishes security fixes for its ImageMagick packages only through Ubuntu Pro, so the image leaves them out rather than ship a library with known vulnerabilities. Most PHP applications, WordPress included, fall back to the GD extension, which is installed. If a site needs Imagick, attach Ubuntu Pro (sudo pro attach) before installing php8.3-imagick, so it receives security updates.

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

SecureAnyCloud backs this image with 24/7 support. Contact sales@secureanycloud.com with the offer name, your VM size and region, and any relevant output from the commands in this guide.

Deploy on Azure

Launch Hestia Control Panel on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure