Application Stacks AWS

Hestia Control Panel on AWS User Guide

| Product: Hestia Control Panel on AWS

Overview

This image runs Hestia Control Panel (HestiaCP), the modern open source web hosting control panel that lets you run a production web server entirely from the browser. From one clean dashboard it manages websites and their nginx plus Apache plus PHP-FPM stack, MariaDB databases, panel users, SSL certificates, cron jobs and the host firewall, and it exposes a REST API for automation.

The panel and its REST API listen on port 8083 over TLS. The image ships a focused web hosting stack: nginx (the panel and the web front end), Apache 2.4 with PHP-FPM (the web backend), MariaDB, and fail2ban with an iptables firewall. Mail (Exim/Dovecot), DNS (BIND) and FTP (vsftpd/proftpd) are deliberately left off, which removes an open SMTP relay and an open recursive resolver — the two worst network-exposure classes for a public cloud image.

On the first boot of every deployed instance, a one shot service derives a per-instance hostname from the resolved public IP, regenerates the panel TLS certificate, rotates the MariaDB root password, mints a fresh administrator password unique to that instance, and records the credentials in /stage/scripts/hestiacp-credentials.log with mode 0600. No shared or default credentials ship in the image. The MariaDB databases of every hosted site live on a dedicated data volume mounted at /var/lib/mysql.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network, inbound port 8083 from the networks your operators will reach the panel on, and inbound ports 80 and 443 for the websites you host through HestiaCP
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Hestia Control Panel. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network, inbound port 8083 from the networks your operators use, and inbound ports 80 and 443 for hosted websites. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation takes a minute or two after the instance state becomes Running and the status checks pass.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Hestia Control Panel Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 8083, 80 and 443 as described above.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=hestiacp-01}]'

The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.

Step 3: Connect and Retrieve Your Credentials

Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the operating system of the AMI variant you launched:

AMI variant SSH login user
Hestia Control Panel 1.9.7 on Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>

The per-instance credentials are written to a root-only file on first boot. Retrieve them with:

sudo cat /stage/scripts/hestiacp-credentials.log

The file contains the panel URL, the admin user, the per-instance admin password, the per-instance hostname, and the per-instance MariaDB root password:

# HestiaCP — Per-VM Credentials (cloudimg)
HESTIA_URL=https://<public-ip>:8083/
HESTIA_ADMIN_USER=admin
HESTIA_ADMIN_PASSWORD=<generated-per-instance>
HESTIA_HOSTNAME=hestia-<ip-with-dashes>.cloudimg.local
HESTIA_MYSQL_ROOT_PASSWORD=<generated-per-instance>

Step 4: Confirm the Stack Is Running

The web hosting stack starts on boot. Confirm the four core services are active:

systemctl is-active hestia nginx apache2 mariadb

All four report active:

active active active active

Confirm the panel version and host summary from the Hestia CLI:

sudo /usr/local/hestia/bin/v-list-sys-info
HOSTNAME                            OS      VER    ARCH    HESTIA  RELEASE  UPTIME
--------                            --      ---    ----    ------  -------  ------
hestia-<ip>.cloudimg.local          Ubuntu  24.04  x86_64  1.9.7   release  13

The MariaDB data directory is a dedicated EBS data volume, mounted at /var/lib/mysql:

findmnt -no SOURCE,TARGET,FSTYPE /var/lib/mysql
/dev/nvme1n1 /var/lib/mysql ext4

Step 5: Sign In to the Panel

Open the HESTIA_URL from step 3 (https://<public-ip>:8083/) in a browser. The panel serves a per-instance self-signed certificate, so accept the browser warning on first use. Enter the username admin, select Next, then enter the per-instance admin password.

Hestia Control Panel sign-in

After signing in you land on the panel dashboard, which summarises users, web domains, databases, cron jobs and backups.

Panel dashboard

Step 6: Host a Website

You can create a web domain from the WEB tab in the dashboard, or from the CLI. The following creates a web domain and reads it back:

sudo /usr/local/hestia/bin/v-add-web-domain admin example-site.test
sudo /usr/local/hestia/bin/v-list-web-domains admin

The new domain is served by the nginx plus Apache plus PHP-FPM stack and appears in the Web view:

Web domains

To issue a Let's Encrypt certificate for a domain that resolves publicly to this instance, use sudo /usr/local/hestia/bin/v-add-letsencrypt-domain admin <your-domain>.

Step 7: Create a Database

Create a MariaDB database and its user, then read the database list back:

sudo /usr/local/hestia/bin/v-add-database admin appdb appuser 'ChangeMe-Str0ng-Pass' mysql
sudo /usr/local/hestia/bin/v-list-databases admin

The database is created on the dedicated MariaDB data volume and appears in the Databases view:

Databases

Step 8: Use the REST API

HestiaCP's REST API is restricted to the loopback interface by default, so local automation on the instance works out of the box while the internet-facing :8083/api/ refuses remote callers. The following authenticated call lists the admin user over loopback and returns 0 on success:

PASS=$(sudo grep '^HESTIA_ADMIN_PASSWORD=' /stage/scripts/hestiacp-credentials.log | cut -d= -f2-)
curl -sk -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'

To allow the API for a specific remote address, add it explicitly with sudo /usr/local/hestia/bin/v-add-sys-api-ip <ip>.

Security Model

  • No default credentials. The build-time administrator password is destroyed before the image is captured, and a fresh per-instance admin password and MariaDB root password are generated on first boot into a root-only file.
  • Minimal network surface. HestiaCP's own iptables firewall is default-deny on input and accepts only ports 22, 80, 443 and 8083. MariaDB is bound to loopback. Mail, DNS and FTP services are not installed.
  • Per-instance identity. The panel hostname and TLS certificate are regenerated per instance from the resolved public IP.
  • Patched base. The base operating system is fully patched, with unattended security updates enabled.

Keep inbound port 8083 restricted to the networks your operators use; expose only ports 80 and 443 broadly, for the websites you host.

Day-Two Operations

  • View or rotate credentials: the credentials file is at /stage/scripts/hestiacp-credentials.log. Change the admin password from the panel or with sudo /usr/local/hestia/bin/v-change-user-password admin '<new-password>'.
  • Manage the server from the CLI: the v-* tools under /usr/local/hestia/bin mirror every panel action (v-list-web-domains, v-add-database, v-list-users, and so on).
  • Service status: systemctl status hestia nginx apache2 mariadb.
  • Firewall: manage rules from the panel's Firewall view or with v-list-firewall / v-add-firewall-rule.
  • Resize storage: grow the root EBS volume for panel and website files, or the /var/lib/mysql data volume for databases, from the EC2 console, then extend the filesystem.

Support

cloudimg provides 24/7 technical support for this product by email at support@cloudimg.co.uk and via live chat. We help with deployment, panel access, hosting websites, HTTPS and Let's Encrypt certificates, MariaDB databases, the host firewall and the REST API.