Installare Ghost su Ubuntu 22.04: scelta dell’architettura
Ghost funziona bene su Ubuntu 22.04 LTS se lo tratti come un servizio applicativo serio, non come un pacchetto “da cliccare e via”. La strada pulita è: utente dedicato, database separato, reverse proxy Nginx, TLS attivo, backup dei file e del database, permessi stretti. Se salti uno di questi punti, il nodo non è Ghost: è l’operatività che diventa fragile.
Qui l’obiettivo è un’installazione ripetibile e leggibile, adatta a un server singolo. Se ti serve alta disponibilità, storage condiviso o replica database, il disegno cambia e va impostato prima, non dopo il deploy.
Prerequisiti minimi e verifica dello stato del server
Prima di toccare Ghost verifica che il sistema sia aggiornato, che il nome host punti al server giusto e che la porta 80/443 sia raggiungibile dall’esterno. Senza questa base, qualsiasi problema di setup si confonde con DNS, firewall o proxy.
Controlli rapidi utili:
lsb_release -a
hostnamectl
ip a
ss -lntp | egrep ':(80|443|3306)\b'
systemctl status ssh --no-pagerSe il server è appena nato, aggiorna subito il sistema e installa gli strumenti base. Su Ubuntu 22.04 conviene anche abilitare gli aggiornamenti di sicurezza automatici, almeno per il profilo LTS.
sudo apt update
sudo apt -y upgrade
sudo apt -y install curl wget unzip gnupg ca-certificates ufwStack consigliato: Nginx, MySQL e Node.js LTS
Ghost richiede Node.js recente e si integra bene con MySQL 8.0 o MariaDB compatibile, anche se su Ubuntu 22.04 la scelta più lineare è MySQL. Nginx fa da reverse proxy e termina TLS. Questa combinazione è semplice da leggere nei log e da gestire nei backup.
La versione di Node va allineata a quella supportata dalla release di Ghost che intendi installare. Non dare per scontato che “ultima LTS” significhi sempre compatibilità totale: controlla la matrice ufficiale della release e chiudi il gap installando la versione richiesta, non quella più comoda.
1. Creare utente e directory di lavoro
Evita di eseguire Ghost come root. Usa un utente dedicato, con home propria e permessi limitati alla directory del sito.
sudo adduser ghostuser
sudo mkdir -p /var/www/ghost
sudo chown ghostuser:ghostuser /var/www/ghostQuesto riduce il blast radius: se un plugin o una dipendenza si rompe, l’impatto resta confinato al servizio applicativo. Il rollback qui è banale: rimuovere la directory e l’utente dedicato se sei ancora in fase di prova.
2. Installare Nginx e aprire il firewall
Nginx serve sia come front-end HTTP sia come punto di controllo per il TLS. Prima di configurarlo, abilita il firewall in modo coerente con il servizio che esporrai.
sudo apt -y install nginx
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status verboseIl controllo minimo è che le porte 80 e 443 risultino ammesse e che Nginx sia in ascolto. Se UFW è già gestito da policy aziendali, non duplicare regole a caso: allineati alla catena esistente.
3. Installare MySQL e preparare il database
Ghost usa un database per contenuti, utenti e configurazione applicativa. Il database va creato con un utente dedicato e privilegi minimi, non con account amministrativi riutilizzati.
sudo apt -y install mysql-server
sudo systemctl enable --now mysql
sudo mysql_secure_installationEntra in MySQL e crea database e utente. Sostituisci la password con una stringa forte generata fuori banda e poi conservata in un password manager; non lasciarla in chiaro nei ticket o nei file condivisi.
sudo mysqlCREATE DATABASE ghostdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ghostuser'@'localhost' IDENTIFIED BY 'PASSWORD_FORTE';
GRANT ALL PRIVILEGES ON ghostdb.* TO 'ghostuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;Verifica subito che l’utente possa autenticarsi e che il database risponda. Se questo passaggio fallisce, non andare avanti con Ghost: hai un problema di credenziali o di permessi, non di CMS.
4. Installare Node.js e Ghost-CLI
Ghost-CLI automatizza gran parte del setup, ma resta sensibile alla versione di Node. Sul server conviene installare una release supportata e poi il tool CLI globale per l’utente dedicato.
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt -y install nodejs
node -v
npm -v
sudo npm install -g ghost-cli@latestSe la tua release di Ghost richiede una versione diversa di Node, cambia il ramo del repository in modo esplicito. Il falso positivo tipico è “installazione riuscita ma avvio KO” per incompatibilità runtime: lo vedi dai log di `ghost log` o da `systemctl status`.
5. Installare Ghost nella directory finale
Entra come utente dedicato e lancia l’installer nella directory corretta. Qui Ghost-CLI chiede nome dominio, configurazione del database, utente admin iniziale e setup di Nginx.
sudo -iu ghostuser
cd /var/www/ghost
ghost installDurante la procedura verifica con attenzione i campi che finiscono in URL pubblici e quelli che definiscono il database. Un errore nel dominio si riflette poi in redirect sbagliati, cookie non validi o link interni rotti.
Se preferisci un’installazione non interattiva, Ghost-CLI supporta parametri e file di configurazione, ma per un primo deploy conviene passare dalla procedura guidata. Il vantaggio è che i controlli di validazione intercettano subito dipendenze mancanti e permessi errati.
6. Configurare il file `config.production.json`
La configurazione effettiva di Ghost vive nel file di produzione, normalmente in `/var/www/ghost/config.production.json`. Qui definisci URL pubblico, bind locale e parametri del database. Non modificare alla cieca: fai prima una copia di backup.
cp /var/www/ghost/config.production.json /var/www/ghost/config.production.json.bakEsempio essenziale:
{
"url": "https://blog.example.com",
"server": {
"host": "127.0.0.1",
"port": 2368
},
"database": {
"client": "mysql",
"connection": {
"host": "127.0.0.1",
"user": "ghostuser",
"password": "PASSWORD_FORTE",
"database": "ghostdb",
"charset": "utf8mb4"
}
}
}Se il server è dietro proxy o CDN, l’URL deve essere coerente con quello realmente pubblicato verso il client. In caso contrario Ghost genera link errati e il login può diventare instabile per mismatch tra schema, host e cookie.
7. Configurare Nginx come reverse proxy
Ghost non va esposto direttamente su Internet sulla porta applicativa. Nginx deve ricevere le richieste esterne e inoltrarle a `127.0.0.1:2368`.
sudo nano /etc/nginx/sites-available/ghostSnippet essenziale:
server {
listen 80;
server_name blog.example.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:2368;
}
}Abilita il sito e testa la sintassi prima del reload. Qui il rollback è immediato: disabiliti il symlink del virtual host e ricarichi Nginx se la configurazione nuova crea problemi.
sudo ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost
sudo nginx -t
sudo systemctl reload nginx8. Abilitare HTTPS con Let’s Encrypt
In produzione il certificato TLS non è opzionale. La parte importante non è solo emetterlo, ma far sì che il redirect HTTP→HTTPS sia coerente con l’URL configurato in Ghost e con il server_name di Nginx.
sudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d blog.example.comDopo il rilascio controlla la scadenza automatica e il rinnovo. Un certificato valido oggi non serve a nulla se non hai verificato il timer di renew e la risposta del server al reload.
systemctl list-timers | grep certbot
sudo certbot renew --dry-run9. Primo accesso e hardening minimo dell’istanza
Terminato il setup, apri il dominio nel browser e completa la creazione dell’account amministratore se non l’hai già fatto nel wizard. Poi riduci la superficie esposta: niente porte applicative pubbliche, niente database in ascolto su tutte le interfacce, niente utenti condivisi.
Controlli utili:
sudo ss -lntp | egrep ':(80|443|2368|3306)\b'
sudo systemctl status ghost_*.service --no-pager
sudo tail -n 50 /var/www/ghost/content/logs/ghost.logSe MySQL è esposto fuori dal loopback, correggi subito. Se Ghost ascolta direttamente su 0.0.0.0 invece che su `127.0.0.1`, stai allargando inutilmente il perimetro d’attacco.
Backup, manutenzione e ripristino
Una installazione fatta bene è una installazione che sai ripristinare. Per Ghost servono almeno due elementi: dump del database e copia della directory `content/`, dove stanno temi, upload e asset. Senza questi due pezzi il restore è parziale.
mysqldump -u ghostuser -p ghostdb > ghostdb.sql
rsync -a /var/www/ghost/content/ /backup/ghost/content/Per il ripristino, l’ordine corretto è database prima, file poi, quindi restart del servizio. Se inverti i passaggi rischi di avviare l’app con dati mancanti o riferimenti a media non ancora presenti.
Problemi tipici e come leggerli senza perdere tempo
Se il sito mostra errore 502, il layer da guardare per primo è Nginx verso Ghost: servizio fermo, porta sbagliata, permessi o crash all’avvio. Se la pagina è bianca dopo il login, controlla i log applicativi e la coerenza dell’URL pubblico. Se il database non risponde, Ghost spesso non parte proprio e il problema si vede subito nel servizio systemd.
Ordine pratico di verifica:
curl -I https://blog.example.com
sudo journalctl -u nginx -n 50 --no-pager
sudo journalctl -u ghost_*.service -n 50 --no-pager
sudo tail -n 100 /var/www/ghost/content/logs/ghost.logSe il problema è dopo un cambio di configurazione, torna al backup del file modificato prima di fare altre ipotesi. In genere è più veloce ripristinare uno snippet noto buono che inseguire sintomi secondari.
Schema operativo che regge nel tempo
La differenza tra una demo e un’installazione gestibile sta nei dettagli operativi: utente dedicato, servizi separati, log consultabili, backup testati, TLS valido e configurazione versionata. Ghost non chiede infrastrutture complesse, ma pretende disciplina. Se la appoggi su un server “arrangiato”, il problema emergerà al primo aggiornamento, al primo rinnovo certificato o al primo restore.
Se devi portarla in produzione vera, aggiungi monitoraggio su uptime HTTP, consumo RAM, spazio disco di `/var/lib/mysql` e integrità del processo Ghost. La metrica minima da osservare è il tasso di errori 5xx e il tempo di risposta del front-end: se peggiora dopo un deploy, hai almeno un segnale per tornare indietro senza discutere per ore.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.