Web Hosting

Install HestiaCP on Ubuntu 26.04/24.04 and Debian 13/12

On a Proxmox guest left on the default CPU type, the HestiaCP installer on Ubuntu 26.04 dies four minutes in with Error: nginx start failed. The nginx.org build for 26.04 needs the x86-64-v3 instruction set, and the default virtual CPU doesn’t expose AVX2, so we had to switch the lab VM to host before it would install HestiaCP on Ubuntu. That trap and two others, a preinstalled UFW package and a cloud-image admin group, aren’t mentioned in the official install docs.

Original content from computingforgeeks.com - post 10146

We cover the supported OS matrix for the 1.10 line, the hst-install.sh options worth setting, a full install with real output, a first site with mail and ProFTPd, panel lockdown, and the way off Debian 11. We ran every command in October 2026 against HestiaCP 1.10.5 on Ubuntu 26.04.1 and 24.04.4 lab VMs. The Debian 13 and 12 notes come from the installer source and the official docs, not from a Debian lab run.

Which systems HestiaCP supports

HestiaCP supports Debian 12 and 13 and Ubuntu 22.04, 24.04 and 26.04 LTS, on AMD64 or ARM64 hardware only. The installer wrapper enforces that list with a single regex check on the release number, so anything else, including Debian 11 and non-LTS Ubuntu, gets refused before a single package is installed. The package repository tells the same story from the other side:

OSCodenameStatusNewest hestia package (Oct 2026)
Ubuntu 26.04 LTSresoluteSupported since 1.10.01.10.5-1+ubuntu26.04
Ubuntu 24.04 LTSnobleSupported1.10.5-1+ubuntu24.04
Ubuntu 22.04 LTSjammySupported1.10.5-1+ubuntu22.04
Debian 13trixieSupported since 1.10.01.10.5-1+debian13
Debian 12bookwormSupported1.10.5-1+debian12
Debian 11bullseyeRemoved in 1.10.51.10.4-1+debian11 (frozen)

We read the last column straight from the Packages index on apt.hestiacp.com for each codename. The bullseye tree stops at 1.10.4, so a Debian 11 server keeps working but never sees the security fixes in the 1.10.5 release notes (session tampering checks, read-only mode bypasses, config injection). Debian’s own LTS for bullseye ended on 31 August 2026, which is why Hestia pulled it. The upgrade section near the end covers the way out.

If you’re choosing between the two Ubuntu releases for a new panel, both get PHP from Ondřej Surý (a Launchpad PPA on 24.04, the packages.sury.org APT repository on 26.04) and 26.04 adds a newer kernel, while 24.04 has two more years of production mileage behind it. Our Ubuntu 26.04 vs 24.04 comparison goes through the rest. Both installed the same HestiaCP build in the lab.

Check the server before you install

HestiaCP wants a freshly installed OS that it can own completely, because the installer writes its own configs for nginx, Apache, PHP-FPM, Exim, Dovecot, BIND and MariaDB and will not merge with anything already there. Before you start, the server needs:

  • a fresh Debian 12/13 or Ubuntu 22.04/24.04/26.04 install with root access
  • 1 GB RAM minimum, 4 GB if you want ClamAV and SpamAssassin
  • 10 GB disk minimum, 40 GB SSD recommended
  • an FQDN such as panel01.example.com with an A record pointing at the server
  • on Ubuntu 26.04, a CPU (physical or virtual) that supports x86-64-v3 (AVX2)

RAM decides more than you’d think. The Ubuntu installer reads /proc/meminfo and quietly changes its defaults: under 1.5 GB it skips both ClamAV and SpamAssassin, under 3 GB it skips ClamAV only, and above that it installs both. So the same command produces two different servers on a 2 GB and a 4 GB VPS. Pass --clamav and --spamassassin explicitly if you want a predictable result.

The CPU check only matters on Ubuntu 26.04. It bites on bare metal older than Intel Haswell or AMD EPYC (pre-AVX2 Xeons, Atom and Celeron boxes) and on VMs whose CPU model hides AVX2. Most cloud VPS plans pass through a modern CPU, but Proxmox defaults to x86-64-v2-AES in the UI and kvm64 in the backend, and neither includes AVX2. The glibc loader will tell you which levels your CPU supports:

/lib64/ld-linux-x86-64.so.2 --help | tail -4

On our lab VM with the default kvm64 CPU, no level is marked as supported, which means baseline x86-64 only:

Subdirectories of glibc-hwcaps directories, in priority order:
  x86-64-v4
  x86-64-v3
  x86-64-v2

You want to see x86-64-v3 (supported, searched) in that list before installing on 26.04. If it’s missing on a Proxmox guest, shut the VM down and set the CPU type to host (or x86-64-v3 on a mixed cluster), then boot it again. Ubuntu 24.04 does not need this, because nginx.org builds its noble package for baseline x86-64, and the same kvm64 VM installed HestiaCP on 24.04 without a complaint.

Prepare Ubuntu or Debian for HestiaCP

The installer must run as root, so switch to a root shell first (on a Debian install with a root password and no sudo, use su - instead). Everything from here on assumes you are root.

sudo -i

Bring the system fully up to date. If the upgrade pulls in a new kernel, reboot before going further so the installer does not run on a half-upgraded box. Both fresh lab images needed that reboot, so expect it and log back in with sudo -i afterwards. Debian doesn’t create /var/run/reboot-required, so on Debian reboot whenever the upgrade installed a new linux-image package.

apt update && apt -y upgrade
ls /var/run/reboot-required 2>/dev/null && reboot

Now set the values you’ll reuse in several commands, in the same root shell you will run the installer from, because a reboot or a new login clears them. The panel hostname must be an FQDN, and the admin username must not already exist as a Linux user or group, which rules out admin on Ubuntu cloud images (more on that below). Change all four to your own:

export HST_HOST="panel01.example.com"
export HST_ADMIN="hcpadmin"
export HST_EMAIL="[email protected]"
export HST_PASS='Ch4nge-This-Passw0rd'

Set the hostname. You do not need to edit /etc/hosts by hand, because the installer appends a 127.0.0.1 line for the hostname whenever the file does not already mention it:

hostnamectl set-hostname "${HST_HOST}"
hostnamectl --static

The second command should print your FQDN back. If /etc/hosts starts with a manage_etc_hosts banner, cloud-init owns that file and rewrites it on every boot, so also set the hostname through your provider’s cloud-init settings (see the troubleshooting entry at the end).

Remove UFW. Ubuntu server images ship it, and Hestia treats it as a conflicting package because the panel manages iptables itself. Leave it in place and a non-interactive install aborts with Error: Hestia Control Panel should be installed on a clean server. Two firewalls on one box is also how people lock themselves out:

apt -y purge ufw

Debian 12 and 13 don’t install UFW by default, so on Debian this step usually prints that the package isn’t installed, which is fine.

Download hst-install.sh and choose options

The script on GitHub is a small wrapper (about 3.5 KB). It detects your OS, refuses unsupported releases, and then downloads and runs the real installer, hst-install-ubuntu.sh or hst-install-debian.sh, passing your flags through. Download it:

wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh

List the options the current release accepts. The help comes from the OS-specific installer, so it reflects what your release will actually do.

bash hst-install.sh -h

On the Ubuntu 26.04 lab VM it printed the full list.

Usage: hst-install-ubuntu.sh [OPTIONS]
  -a, --apache            Install Apache        [yes|no]  default: yes
  -w, --phpfpm            Install PHP-FPM       [yes|no]  default: yes
  -o, --multiphp          Install MultiPHP      [yes|no]  default: no
  -v, --vsftpd            Install VSFTPD        [yes|no]  default: yes
  -j, --proftpd           Install ProFTPD       [yes|no]  default: no
  -k, --named             Install BIND          [yes|no]  default: yes
  -m, --mysql             Install MariaDB       [yes|no]  default: yes
  -M, --mysql8            Install MySQL 8       [yes|no]  default: no
  -g, --postgresql        Install PostgreSQL    [yes|no]  default: no
  -x, --exim              Install Exim          [yes|no]  default: yes
  -z, --dovecot           Install Dovecot       [yes|no]  default: yes
  -Z, --sieve             Install Sieve         [yes|no]  default: no
  -c, --clamav            Install ClamAV        [yes|no]  default: yes
  -t, --spamassassin      Install SpamAssassin  [yes|no]  default: yes
  -i, --iptables          Install iptables      [yes|no]  default: yes
  -b, --fail2ban          Install Fail2Ban      [yes|no]  default: yes
  -q, --quota             Filesystem Quota      [yes|no]  default: no
  -L, --resourcelimit     Resource Limitation   [yes|no]  default: no
  -W, --webterminal       Web Terminal          [yes|no]  default: no
  -d, --api               Activate API          [yes|no]  default: yes
  -r, --port              Change Backend Port             default: 8083
  -l, --lang              Default language                default: en
  -y, --interactive       Interactive install   [yes|no]  default: yes
  -s, --hostname          Set hostname
  -e, --email             Set admin email
  -u, --username          Set admin user
  -p, --password          Set admin password
  -D, --with-debs         Path to Hestia debs
  -f, --force             Force installation
  -h, --help              Print this help

Two details differ from the options page in the docs. -L, --resourcelimit exists in the installer but is not on the docs page yet, and the clamav and spamassassin defaults shown here are the 4 GB values, which shrink on smaller servers as described above. Most servers only need decisions on these:

  • --apache no for nginx with PHP-FPM only (no .htaccess support)
  • --clamav no --spamassassin no on servers under 4 GB, or with no mail
  • --proftpd yes --vsftpd no if you want ProFTPd instead of vsftpd
  • --multiphp '8.3,8.4,8.5' to install several PHP versions
  • --named no if DNS stays with Cloudflare or your registrar

Always pass --username. In non-interactive mode the installer no longer picks a default admin name, and with no terminal to ask it loops forever on Please use a valid username (ex. user). The lab run printed that line 221,876 times in 20 seconds before timeout killed it.

Install HestiaCP on Ubuntu or Debian

We used the full-stack command below on Ubuntu 26.04, with defaults everywhere except ProFTPd in place of vsftpd. It installs nginx in front of Apache, PHP-FPM, BIND, Exim with ClamAV and SpamAssassin, Dovecot, MariaDB, ProFTPd, and iptables with Fail2Ban:

bash hst-install.sh --interactive no \
  --hostname "${HST_HOST}" \
  --username "${HST_ADMIN}" \
  --email "${HST_EMAIL}" \
  --password "${HST_PASS}" \
  --proftpd yes --vsftpd no

For a lighter web server with nginx and PHP-FPM, no Apache and no mail scanning, this is the variant that ran on Ubuntu 24.04. It’s the better starting point on a 2 GB VPS:

bash hst-install.sh --interactive no \
  --hostname "${HST_HOST}" \
  --username "${HST_ADMIN}" \
  --email "${HST_EMAIL}" \
  --password "${HST_PASS}" \
  --apache no --clamav no --spamassassin no

The installer first prints the version and the component list, so check it before walking away. On the 26.04 run it showed this:

                          Hestia Control Panel
                                  1.10.5
                            www.hestiacp.com

========================================================================

Thank you for downloading Hestia Control Panel! In a few moments,
we will begin installing the following components on your server:

   - NGINX Web / Proxy Server
   - Apache Web Server (as backend)
   - PHP-FPM Application Server
   - Bind DNS Server
   - Exim Mail Server + ClamAV + SpamAssassin
   - Dovecot POP3/IMAP Server
   - MariaDB Database Server
   - ProFTPD FTP Server
   - Firewall (iptables) + Fail2Ban Access Monitor

========================================================================

Installation backup directory: /root/hst_install_backups/251020261629
Installation log file: /root/hst_install_backups/hst_install-251020261629.log

Adding required repositories to proceed with installation:

[ * ] NGINX
[ * ] PHP
[ * ] MariaDB 11.8
[ * ] Hestia Control Panel

It adds four external repositories (nginx.org, Surý’s PHP, MariaDB 11.8 and Hestia’s own) and then installs everything from them. The installer warns that this takes 10 to 15 minutes, but on a 2 vCPU, 4 GB VM it took 6m28s for the full stack on 26.04 and 4m29s for the lean stack on 24.04. A successful run ends like this, with the public IP that Hestia detected as the backup URL:

Congratulations!

You have successfully installed Hestia Control Panel on your server.

Ready to get started? Log in using the following credentials:

	Admin URL:  https://panel01.example.com:8083
	Backup URL: https://203.0.113.10:8083
 	Username:   hcpadmin
	Password:   The password you chose during installation.

With --interactive no the installer doesn’t reboot for you. The last line it prints is [ ! ] IMPORTANT: You must restart the system before continuing!, so do that now:

reboot

The full installer log stays in /root/hst_install_backups/, along with copies of every config file it replaced. Keep it until the server is in production, because it is the first place to look when a service fails later.

Verify the install

After the reboot, log in again and switch to root with sudo -i. The Hestia v-* commands live in /usr/local/hestia/bin, which root’s login shell now has in its PATH. Start with the system summary:

v-list-sys-info

HESTIA is the version you are running and RELEASE is the update channel. Our Ubuntu 26.04 lab box returned this.

HOSTNAME             OS      VER    ARCH    HESTIA  RELEASE  UPTIME  LA
--------             --      ---    ----    ------  -------  ------  --
panel01.example.com  Ubuntu  26.04  x86_64  1.10.5  release  0       1.96  /  0.47  /  0.15

Then check that every service came back after the reboot. MEM is in megabytes.

v-list-sys-services

We had all fourteen services running on the full stack, with the version line from v-list-sys-info above them:

v-list-sys-info and v-list-sys-services output for HestiaCP 1.10.5 on Ubuntu 26.04

ClamAV is the biggest process on the box at almost 1 GB, more than MariaDB. Here is how the two installs compared right after their first reboot, both on 4 GB VMs with no sites yet:

InstallInstall timeRAM used after bootLargest processes
Ubuntu 26.04, full stack (Apache, ClamAV, SpamAssassin, ProFTPd)6m28s1,764 MBClamAV 996 MB, MariaDB 662 MB, Apache 446 MB, spamd 377 MB
Ubuntu 24.04, lean (no Apache, ClamAV or SpamAssassin)4m29s640 MBMariaDB 684 MB, Fail2Ban 158 MB, BIND 83 MB

Per-service MEM comes from Hestia’s process accounting and free counts differently, which is why MariaDB alone can exceed the lean box’s total. Nearly all of that 1.1 GB gap is ClamAV, SpamAssassin and Apache. On a 2 GB VPS we’d start with the lean profile, which leaves room for PHP workers and MariaDB buffers, while the full profile would be swapping before the first WordPress site goes live. Turn mail scanning on later only if the server actually handles mail for users.

Finally, confirm what’s listening on the public-facing ports:

ss -tlnp | grep -E ':(21|22|25|53|80|443|587|993|3306|8083) '

Trimmed to the address and process columns, the full-stack box showed the panel’s own nginx (hestia-nginx) on 8083 for all interfaces, the public nginx on 80 and 443 bound to the server’s address, and MariaDB on localhost only. Apache’s 8080 and 8443 are not in this filter, and iptables drops them anyway:

0.0.0.0:8083        hestia-nginx
0.0.0.0:22          sshd
0.0.0.0:25          exim4
127.0.0.1:3306      mariadbd
10.0.1.50:53        named
10.0.1.50:80        nginx
0.0.0.0:587         exim4
10.0.1.50:443       nginx
0.0.0.0:993         dovecot
*:21                proftpd

The diagram shows the same layout as a picture. Only the ports in the firewall’s allow list reach the box, and MariaDB never listens beyond localhost. On the lean profile the Apache hop disappears and nginx talks to PHP-FPM directly.

HestiaCP architecture: iptables and Fail2Ban admit ports 80, 443, 8083, mail, DNS and FTP; nginx proxies to Apache and PHP-FPM, which use MariaDB on localhost

If 8083 is missing from that output, the panel didn’t start, and systemctl status hestia will say why.

Log in and add your first site

Open https://panel01.example.com:8083 in a browser. The certificate is self-signed until you issue a Let’s Encrypt one, so accept the warning. The login is two steps in this release: you type the username, click Next, and only then get the password field.

HestiaCP login page asking for the username first on Ubuntu 26.04

The gear icon at the top right opens the server page, which shows the Hestia version, the OS and every service with its memory use. It is the same data as v-list-sys-services, and it’s the quickest health check once you are in the browser:

HestiaCP server page showing version 1.10.5 on Ubuntu 26.04 with service memory use

Don’t host sites under the admin account, because a site running as the admin user carries the admin’s privileges if it gets compromised. Create a standard user instead. The arguments are username, password, email, package and display name:

v-add-user siteuser 'Site-User-Pass1' [email protected] default "Site User"
v-list-users

v-add-user prints nothing on success, and the listing confirms both accounts.

USER      ROLE   PKG      WEB  DNS  MAIL  DB  DISK  BW  SPND  DATE
----      ----   ---      ---  ---  ---   --  ----  --  ----  ----
hcpadmin  admin  default  1    0    0     0   0     0   no    2026-10-25
siteuser  user   default  0    0    0     0   0     0   no    2026-10-25

Now add the site. The panel’s Add Web Domain form ticks DNS and mail support for you, but the CLI does not: v-add-web-domain creates only the web vhost, and a later v-add-mail-account fails with Error: mail domain example.com doesn't exist. On the command line, add the three parts separately. The IP on v-add-dns-domain is the address your A records should point to:

v-add-web-domain siteuser example.com
v-add-dns-domain siteuser example.com 203.0.113.10
v-add-mail-domain siteuser example.com
v-add-mail-account siteuser example.com info 'Mail-Pass-123'

The document root is /home/siteuser/web/example.com/public_html, seeded with a placeholder index.html and robots.txt. A request with the right Host header already returns the placeholder page:

curl -s -o /dev/null -w "%{http_code} %{size_download}\n" -H "Host: example.com" http://10.0.1.50/

A 200 and the 2,542-byte placeholder means nginx is serving the vhost. The lab sits behind NAT, so nginx binds the LAN address (10.0.1.50 here) while Hestia records the public address it detected (203.0.113.10) for DNS and the backup URL. Logged in as siteuser, the panel’s web list shows the domain with SSL and statistics still off:

HestiaCP web domain list for a standard user after adding example.com

The DNS zone gets 15 records on creation: NS, the A records for the domain and mail, the www, ftp and webmail CNAMEs, MX, an SPF TXT record, DMARC at p=quarantine and SRV records for submission, IMAP, IMAPS, POP3 and POP3S. DKIM is generated with the mail domain, and v-list-mail-domain-dkim-dns siteuser example.com prints the TXT record to publish if your DNS lives elsewhere. The mail list confirms anti-virus, spam filtering and DKIM are on:

HestiaCP mail domain with anti-virus, spam filter and DKIM enabled

Databases get the owner’s name as a prefix, so a database called app for siteuser becomes siteuser_app, with a user of the same name:

v-add-database siteuser app app 'Db-Pass-123' mysql
v-list-databases siteuser

Your application needs the prefixed name from this listing in its config, with localhost as the host.

DATABASE      USER          HOST       TYPE   DISK  SPND  DATE
--------      ----          ----       ----   ----  ----  ----
siteuser_app  siteuser_app  localhost  mysql  0     no    2026-10-25

From here a WordPress or Laravel site can go in through the Quick Install App button on the domain’s edit page, or over SFTP with the siteuser credentials.

Use ProFTPd on Ubuntu 26.04 and Debian 13

ProFTPd with TLS works on Ubuntu 26.04 and Debian 13 from 1.10.5 onward. Before that release, ProFTPd on those two systems did not load its TLS module, because Hestia’s proftpd.conf never included modules.conf, and on Ubuntu 26.04 AppArmor also blocked ProFTPd from reading the panel certificate. PR #5677 fixed both, and the lab install shows the result:

grep -n Include /etc/proftpd/proftpd.conf
cat /etc/apparmor.d/local/proftpd

Both pieces are in place: modules.conf now loads before tls.conf, and a local AppArmor rule lets ProFTPd read the certificate and create its socket:

7:Include /etc/proftpd/modules.conf
8:Include /etc/proftpd/tls.conf
# Configuration added by Hestia
/usr/local/hestia/ssl/certificate.crt r,
/usr/local/hestia/ssl/certificate.key r,
/run/proftpd.sock rw,

Add an FTP account to the site and test it with explicit TLS. Hestia prefixes the FTP user with the owner, so deploy becomes siteuser_deploy:

v-add-web-domain-ftp siteuser example.com deploy 'Ftp-Pass-123'
curl -sS --ssl-reqd -k --list-only ftp://siteuser_deploy:[email protected]/

A listing of the domain’s directory came back, which proves the TLS handshake and login both worked on ProFTPd 1.3.9.

stats
private
document_errors
..
.
logs
public_html
cgi-bin

The same curl without --ssl-reqd also succeeds, because Hestia ships TLSRequired off in /etc/proftpd/tls.conf. Plain FTP sends the password in clear text, so set TLSRequired on there and run v-restart-ftp unless an old client forces your hand. If you installed ProFTPd on 26.04 or Debian 13 before 1.10.5, you do not have to redo anything by hand. The 1.10.5 package’s upgrade script checks proftpd.conf and modules.conf and applies the same fix when the package updates.

Issue Let’s Encrypt certificates

Let’s Encrypt needs the domain to resolve to the server and port 80 to be reachable from the internet. The lab VMs had neither, and they used the reserved example.com names, so this part follows Hestia’s documented commands rather than a successful lab run. For a site, tick “Enable SSL for this domain” and “Use Let’s Encrypt” on the domain’s edit page, or run:

v-add-letsencrypt-domain siteuser example.com

To replace the panel’s self-signed certificate on port 8083, issue one for the hostname itself.

v-add-letsencrypt-host

A real domain that does not resolve to the server yet gets past the order step and fails at validation, with Let's Encrypt validation status ... followed by the CA’s details, or Let's Encrypt domain verification failed. Both strings come from v-add-letsencrypt-domain. The installer also drops an @reboot job in /etc/cron.d/hestia-ssl that retries the host certificate once, so a panel whose DNS was already correct at install time often has a valid certificate after the first reboot. Renewals run once a day from the hestiaweb crontab, at a time the installer picks at random between 01:00 and 07:59 (04:15 on our box; crontab -l -u hestiaweb shows yours).

Back up user accounts

Hestia backs up every user nightly at 05:10 into /backup, with web files, DNS zones, mail, databases, cron jobs and home directories in one tarball per user. Run one by hand to confirm it works before you rely on it:

v-backup-user siteuser
v-list-user-backups siteuser

At the end of the backup output, the summary gives the path and size, and the listing confirms Hestia registered it.

-- SUMMARY --
2026-10-25 16:38:37 Local: /backup/siteuser.2026-10-25_16-38-37.tar
2026-10-25 16:38:37 Size: 1 MB
2026-10-25 16:38:37 Runtime: 1 minute
BACKUP                            TYPE   SIZE  TIME  DATE
------                            ----   ---   ----  ----
siteuser.2026-10-25_16-38-37.tar  local  1     1     2026-10-25

A backup on the same disk does not survive a dead disk. Add a remote target under Server settings, Backups, or with v-add-backup-host (SFTP, FTP, rclone remotes or Backblaze B2) or v-add-backup-host-restic for incremental restic repositories. If you set up B2 on an older release and it never authenticated, upgrade first: 1.10.5 fixed the B2 setup passing the raw password instead of the processed one (#5697), and also fixed restic full restores (#5709). Restore a single user with v-restore-user siteuser siteuser.2026-10-25_16-38-37.tar.

Lock down the panel port

The default firewall accepts the panel port 8083 from anywhere, along with SSH, web, mail, DNS and FTP, and drops everything else. Fail2Ban watches the panel login, but an admin panel open to the internet is still the first thing to close. The obvious move, adding a new rule for your office IP, doesn’t close anything on its own:

v-add-firewall-rule ACCEPT 198.51.100.25 8083 TCP "Admin office"

Rule 11 is the new one, but rule 2 still accepts 8083 from 0.0.0.0/0, so anyone can still reach the login page:

HestiaCP firewall rules list with an extra rule for the panel port

The 1.10 line added rule ordering (the Pos column, and v-move-firewall-rule RULE up|down on the CLI), which matters for DROP rules, but for an allow list the fix is to narrow rule 2 itself. Make sure you’re adding your current public IP (the address your browser reaches the server from; who am i in your SSH session shows the source address, but over a VPN or NAT that is the inner address, not the public one the panel sees), or you will lock yourself out of the panel (SSH on rule 10 keeps working, so you can undo it):

v-delete-firewall-rule 11
v-change-firewall-rule 2 ACCEPT 198.51.100.25 8083 TCP HESTIA
iptables -S INPUT | grep 8083

Only the fail2ban jump and the single-source ACCEPT should be left for 8083.

-A INPUT -p tcp -m tcp --dport 8083 -j fail2ban-HESTIA
-A INPUT -s 198.51.100.25/32 -p tcp -m tcp --dport 8083 -j ACCEPT

After that change, our request to the panel from another address timed out. While you are in there, delete the rules for services you didn’t install (the IMAP and POP3 rules on a server with no mail, for example). Then turn on two-factor authentication for the admin from the user menu, top right, which is the panel equivalent of v-add-user-2fa, and store the recovery code it shows you. Our Fail2ban on Ubuntu 26.04 guide explains jail tuning if the default ban times are too soft for you. The post-install checklist for Ubuntu 26.04 server covers SSH keys and unattended upgrades, both of which apply to a Hestia box too.

Upgrade HestiaCP and move off Debian 11

HestiaCP updates itself. The installer adds v-update-sys-hestia-all to the hestiaweb crontab at 04:41 every day, and the packages come from apt.hestiacp.com, so a normal apt update && apt upgrade also picks up new releases. You can turn automatic updates off under Server, Updates. Check what’s installed and what the repository offers:

apt-cache policy hestia | head -6

Packages from 1.10.0 onward carry the distro in the version string, which makes it obvious which tree you’re on:

hestia:
  Installed: 1.10.5-1+ubuntu26.04
  Candidate: 1.10.5-1+ubuntu26.04
  Version table:
 *** 1.10.5-1+ubuntu26.04 500
        500 https://apt.hestiacp.com resolute/main amd64 Packages

On Debian 11 that candidate will never go past 1.10.4-1+debian11. A fresh install there does not get that far: the wrapper prints Your operating system (OS) is not supported by Hestia Control Panel and lists Debian 12 and 13 and Ubuntu 22.04, 24.04 and 26.04 as the supported releases. Reinstalling on a new Debian 13 server and restoring user backups is the cleanest route if the box is small. In-place upgrades work too, one release at a time, and Hestia’s OS upgrade notes list what breaks at each hop:

  1. Take a backup of every user and copy it off the server.
  2. Update Hestia to the last bullseye build with apt update && apt upgrade.
  3. Upgrade Debian 11 to 12, then replace the Exim template with the 4.95 one from /usr/local/hestia/install/deb/exim/ as the docs show.
  4. On Debian 12, check that the APT sources in /etc/apt/sources.list.d are not commented out, then apt update && apt upgrade to reach the current release.
  5. Optionally continue to Debian 13 using the steps below.

For the 12 to 13 hop, Hestia’s docs add two steps around the normal Debian procedure. MariaDB must be on 11.8 before you switch codenames, because the MariaDB repository has no 11.4 build for trixie. After the upgrade you run Hestia’s migration script so Dovecot, BIND and Exim pick up configs that match the new versions. These are the commands from the docs, run as root:

sed -i -E 's|mariadb-server/[0-9]+\.[0-9]+/repo/|mariadb-server/11.8/repo/|' /etc/apt/sources.list.d/mariadb.list
apt-get update && apt-get -y full-upgrade

Then switch the codename everywhere, run the full upgrade with your existing config files kept, and migrate.

sed -i 's/bookworm/trixie/g' /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources
apt-get update
DEBIAN_FRONTEND=noninteractive UCF_FORCE_CONFFOLD=1 apt-get -y full-upgrade -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"
/usr/local/hestia/install/upgrade/manual/migrate_conf_to_debian_13.sh

Reboot, then run v-list-sys-services and look for anything not running. Our Debian 12 to 13 upgrade guide covers the OS side in more detail. Ubuntu 24.04 to 26.04 follows the same pattern with one extra step: the Ondřej Surý Launchpad PPAs don’t serve 26.04, so the docs have you swap them for packages.sury.org before changing noble to resolute, and then run migrate_conf_to_ubuntu_26.04.sh. If the box runs on a Proxmox VM, fix the CPU type before that upgrade too, or nginx won’t start afterwards.

If you are still weighing panels, CloudPanel is lighter and PHP-only, and CyberPanel runs OpenLiteSpeed instead of nginx. For the nginx and Apache layers underneath it, our pick of books for learning Apache and Nginx covers the config skills you’ll need once you start editing Hestia’s templates.

Fix common HestiaCP install errors

Every error below was produced on the lab VMs, apart from the Debian 11 message, which comes straight from the installer source.

Error: nginx start failed (CPU ISA level is lower than required)

The installer stops right after [ * ] Updating Cloudflare IP Ranges for Nginx... on Ubuntu 26.04 with Error: nginx start failed. The journal gives the real cause:

systemctl status nginx --no-pager

On the kvm64 VM the last journal lines in that status output showed the binary refusing to run.

Oct 25 16:23:46 panel01.example.com systemd[1]: Starting nginx.service - nginx - high performance web server...
Oct 25 16:23:46 panel01.example.com nginx[65851]: /usr/sbin/nginx: CPU ISA level is lower than required
Oct 25 16:23:46 panel01.example.com systemd[1]: nginx.service: Control process exited, code=exited, status=127/n/a
Oct 25 16:23:46 panel01.example.com systemd[1]: nginx.service: Failed with result 'exit-code'.
Oct 25 16:23:46 panel01.example.com systemd[1]: Failed to start nginx.service - nginx - high performance web server.

readelf -n /usr/sbin/nginx on that box reports x86 ISA needed: x86-64-baseline, x86-64-v2, x86-64-v3 for the 1.31.8-1~resolute package, while the noble build of the same version needs only x86-64-baseline. The virtual CPU has to expose AVX2. On Proxmox, set the VM’s CPU type to host or x86-64-v3, power the VM off and on so Proxmox applies the pending CPU change, and run the installer on a fresh OS. We rebuilt the VM rather than re-running over the half-finished install, which is the safer choice because the installer had already created the admin account and written configs.

Error: Hestia Control Panel should be installed on a clean server.

Just above this line, the installer lists the conflicting packages. On stock Ubuntu images we only ever saw UFW there.

WARNING: The following packages are already installed
ufw*

It is highly recommended that you remove them before proceeding.

!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!

Error: Hestia Control Panel should be installed on a clean server.

In interactive mode it offers to purge them for you. In non-interactive mode there’s nobody to answer, so it aborts. Run apt -y purge ufw and start the installer again. If the list shows nginx, apache2, mariadb or exim4, the server isn’t clean, and a reinstall of the OS beats fighting the installer with --force.

Please use a valid username (ex. user). repeated forever

You ran a non-interactive install without --username from something with no terminal on stdin (a script, cloud-init, or ssh without a TTY). The installer asks for a name with read, gets nothing, and asks again in a tight loop. In a normal interactive SSH session it just waits at Please enter administrator username: instead. Press Ctrl+C and add --username to the command. Nothing is half-installed at that point, because the check runs before any Hestia package goes in.

Username or Group allready exists please select a new user name

The installer checks the admin name against both /etc/passwd and /etc/group. The Ubuntu 26.04 and 24.04 cloud images we used both carry an admin group (GID 107 and 110), so --username admin, the name in most older guides, fails there. Your own login name fails too, because that user already exists. Pick a name that is neither, such as hcpadmin, and confirm it is free first with getent passwd hcpadmin; getent group hcpadmin, which should print nothing.

Error: Let’s Encrypt new auth status 400

Let’s Encrypt refused the new order itself, before any HTTP challenge. That step checks policy, not DNS, so a 400 there means a name the CA won’t issue for (reserved names such as example.com, which is what the lab got for example.com and panel01.example.com), a malformed name, or a rate limit. Use a real domain you control. If the name is real but doesn’t point at the server yet, you’ll see the validation or verification error from the certificate section instead: check dig +short example.com from outside the server, make sure rule 9 still allows 80 and 443, and retry. For the panel hostname the 400 is followed by Error: Let's Encrypt SSL creation failed, and the panel simply keeps its self-signed certificate.

sudo: unable to resolve host panel01.example.com

Your FQDN is not in /etc/hosts and DNS can’t resolve it yet. It’s harmless for sudo, but Exim and the panel use the hostname, so fix it. On our 24.04 cloud image, cloud-init rewrote /etc/hosts at boot and threw away the line added before the install, and a manage_etc_hosts: false drop-in in /etc/cloud/cloud.cfg.d/ did not stop it, because the Proxmox-generated user-data sets the opposite. Adding the line by hand didn’t clear the warning on that box either, so fix it where cloud-init gets the name. On a VPS, set the hostname in the provider’s panel. On Proxmox, cloud-init builds the FQDN from the VM name plus the Cloud-Init DNS domain, so name the VM panel01, set the DNS domain to example.com, click Regenerate Image and reboot.

Your operating system (OS) is not supported by Hestia Control Panel

That’s the wrapper refusing your release, typically Debian 11 or a non-LTS Ubuntu, before anything is downloaded. There’s no flag to override it. Install on Debian 12 or 13 or a current Ubuntu LTS instead, or upgrade the OS first as described in the upgrade section above.

Keep reading

Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 Security UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Php PHP2Shell on End-of-Life PHP 8.1, 8.0 and 7.4 (WHMCS, ionCube) Upgrade a Single Package on Ubuntu / Debian with apt Debian Upgrade a Single Package on Ubuntu / Debian with apt APT Cheat Sheet: apt and apt-get Commands for Ubuntu/Debian Cheat Sheets APT Cheat Sheet: apt and apt-get Commands for Ubuntu/Debian Enable ionCube and SourceGuardian PHP Loader on cPanel Web Hosting Enable ionCube and SourceGuardian PHP Loader on cPanel

7 thoughts on “Install HestiaCP on Ubuntu 26.04/24.04 and Debian 13/12”

Leave a Comment

Press ESC to close