Vai al contenuto

Hestia Control Panel su 8 server: la prima infra Romiltec, scelte e rimpianti

Hestia Control Panel su 8 server: la prima infra Romiltec, scelte e rimpianti

Hestia Control Panel su 8 server: la prima infra Romiltec, scelte e rimpianti

Agosto 2023, primi mesi di Romiltec. Avevo otto server bare-metal da configurare in pochi giorni: tre Hetzner in Germania, due OVH in Francia, tre macchine Proxmox interne. Sopra ci dovevano girare una trentina di siti WordPress di clienti editoriali, qualche staging Laravel, un cubo MariaDB con repliche slave per i picchi traffico. La domanda non era cosa metto sopra: era come faccio a non passare le notti a fare strace su processi php-fpm impazziti. La risposta è stata Hestia Control Panel su tutti i nodi. Vedi anche gli altri post di Production.

Perché HestiaCP e non Plesk, cPanel, o niente

Avevo tre opzioni concrete sul tavolo. Plesk e cPanel: licenze a pagamento, vendor lock-in, GUI pesanti, e soprattutto curve di customizzazione faticose quando devi infilare cose tipo fastcgi_cache con header custom o un override nginx specifico per un REST endpoint WordPress. La terza opzione era niente control panel: nginx + php-fpm + bind + postfix + certbot tutto a mano, magari spruzzato con un po’ di Ansible.

Per una software house di una persona e mezzo a metà 2023, il niente control panel è una scelta romantica. Ti senti senior dev, scrivi i tuoi playbook, controlli ogni byte. Poi alle 23:30 un cliente apre un ticket perché il certificato Let’s Encrypt non si è rinnovato e tu sei davanti a journalctl -u certbot.timer invece di essere a letto. Hestia è scritto in shell e Bash, è leggibile, è MIT, e soprattutto fa la cosa giusta di default: nginx in front di Apache (o php-fpm puro, configurabile per pool), Postfix con DKIM e SPF, Bind, fail2ban, ClamAV via spamd, certbot integrato nativamente con il flusso v-add-letsencrypt-domain, backup base con v-backup-user. Tutta roba che ti serve dal giorno 1.

La scelta non era Hestia è meglio di Plesk. Era Hestia mi fa spendere zero ore in plumbing standard, e ho otto server da mettere in produzione per ieri.

Lo schema che ho replicato su tutti gli 8 nodi

Ogni server, indipendentemente dal cloud provider, è stato standardizzato così:

  • Debian 12 base, kernel stock, niente custom build
  • HestiaCP installato via script ufficiale hst-install-debian.sh con flag --apache=no --proftpd=no --named=yes --vsftpd=no --exim=yes --dovecot=yes --clamav=no --spamassassin=no --iptables=yes --fail2ban=yes
  • Pool php-fpm separati per versione (7.4, 8.0, 8.1, 8.2 inizialmente, poi via via 8.3 e 8.4)
  • nginx come unico front, niente Apache nemmeno come backend
  • MariaDB locale per i siti piccoli, MaxScale + replica master-slave per i due grossi gruppi editoriali
  • Redis locale per object cache WordPress (un Redis per server, namespace per dominio)
  • restic + Backblaze B2 (eu-central-003) per i backup, schedulati cron alle 04:00 a minuti scaglionati
  • Cloudflare davanti a tutto, full strict, certificati Let’s Encrypt sull’origin

La parte più importante è quella che non si vede: ogni cosa che faccio fuori da HestiaCP la traccio in un repo runbook interno come markdown. Override nginx per un dominio specifico? Template clone nella directory standard dei template Hestia. Backup customizzato? Script personalizzati in homedir utente. Fix a mano dell’fstab per un dataset ZFS? Annotato. Hestia rigenera spesso le sue config dai template, e se modifichi nginx.conf direttamente perdi tutto al primo v-rebuild-web-domains.

Le scelte che rifarei

Tre, in ordine di importanza.

Una. Standardizzare la stessa stack su tutti i nodi. La fatica di configurare il primo server si paga una volta: dal secondo in poi è copia-incolla con sed. Quando nel 2024 ho dovuto migrare un editore intero da WordPress.com a infra dedicata in undici giorni (lo racconto in un altro post di Fieldwork), avevo già lo stampino: bastava istanziare un nuovo server Hestia con lo script standard e copiare i file.

Due. Tenere il control panel come interfaccia, non come padrone. Hestia gestisce gli oggetti che la GUI sa toccare (utenti, domini, DB, cron base). Tutto quello che è custom (template nginx clonati, override fastcgi cache, script restic, monitoring Prometheus node_exporter) sta fuori. Così posso aggiornare HestiaCP senza che mi spari via le customizzazioni.

Tre. Niente Apache in stack. nginx + php-fpm puro, sempre. Sui nodi editoriali con picchi tipo 5000 req/s su una landing virale di un articolo che spara su Discover, Apache sarebbe morto al primo colpo. nginx + fastcgi_cache regge senza nemmeno scaldarsi.

I rimpianti

Anche tre, e fanno più male.

Uno. Hestia non ha cluster nativo. Ogni nodo è un’isola: utenti separati, domini separati, certificati separati. Non c’è un orchestrator che ti dice questo dominio gira sul nodo X, replicalo sul nodo Y. Quando devi gestire alta affidabilità per un sito editoriale serio (DB master-master con MaxScale, file replicati con lsyncd), tutto questo lo costruisci sopra Hestia, non con Hestia. Il control panel non sa che il dominio è multi-nodo: lo configuri identico su entrambi i nodi e poi gestisci la sync con script esterni. Funziona, ma la verità operativa è che quando promuovi uno slave a master, devi entrare in HestiaCP di entrambi i nodi e ricontrollare a mano. Non è elegante.

Due. I backup di base sono backup, non disaster recovery. v-backup-user ti tira fuori un tar con i file e il dump SQL, lo butta in /backup/. Bello per recuperare un file cancellato per sbaglio. Inutile se il datacenter brucia. Per il DR vero ho dovuto montarmi sopra restic + Backblaze B2 con script wrapper standardizzati per tutto il fleet. Il fatto che Hestia non distingua tra file backup e backup off-site cifrato è un debito che paghi quando il cliente ti chiede quanto ci mettete a tirarci su tutto da zero?.

Tre. Niente ZFS-friendly storage layout di default. Hestia mette tutto in /home/<user>/web/<domain>/ su /, e se ti dimentichi di pre-creare un dataset dedicato per /home, ti ritrovi gli snapshot a livello di filesystem unico. Sui server Proxmox interni che usavamo per i progetti più grossi questo conta: io oggi con Proxmox creo un dataset ZFS per ogni utente Hestia, snapshot orari, retention 7 giorni. Ma è una cosa che ho imparato sul secondo round, non sul primo.

Quello che è cambiato dopo

Tre anni dopo, ad agosto 2026, l’infra Romiltec è cresciuta. Sono diciassette server HestiaCP più due nodi Docker (Portainer + Jenkins su una macchina, OpenSearch cluster su LXC su un’altra), un cluster Proxmox sul nodo Kobol per i progetti R&D interni, MaxScale con replica circolare master-master su due DB server (nomi-codice interni james e jason, cubo che racconto in dettaglio in un altro post di Production), backup restic consolidati in due bucket EU. La superficie è dieci volte quella del 2023, ma il pattern di base è lo stesso: HestiaCP come control panel single-node, tutto il resto sopra.

Hestia non è una piattaforma. È un set di shell script in MIT che ti tolgono dalla testa il plumbing che nessuno ha voglia di scrivere. Per una software house bootstrap che parte da zero con sei zeri di clienti che pagano da subito, è la scelta razionale. Quando il fatturato cresce e i clienti diventano più esigenti, ci costruisci sopra l’orchestrazione che ti serve. Ma il giorno zero, quando devi accendere otto server e mandare in produzione una trentina di siti senza svegliarti la notte, Hestia fa esattamente quello che serve: ti tira fuori dal plumbing e ti lascia il tempo di costruire le cose che ti differenziano.

Il software open-source di HestiaCP è ancora oggi il punto di partenza di ogni nuovo nodo che alziamo. Per chi viene dal mondo Plesk o cPanel, è uno shock leggibile: tutto è bash, tutto è hookable, tutto è tuo. Per chi viene dal mondo Kubernetes, è un passo indietro che però costa zero in licenze e tempo di apprendimento. Per Romiltec di metà 2023, era esattamente la cosa giusta.