Pourquoi auto-héberger Ghost sur un VPS
Ghost combine ce que WordPress fait laborieusement et ce que Substack facture cher : un éditeur épuré, des performances natives excellentes (Node.js), une gestion de membres et d'abonnements payants intégrée via Stripe, et l'envoi de newsletters sans plugin. Mais Ghost(Pro) facture à l'audience, et les plateformes de newsletter prennent une commission sur vos revenus.
En l'hébergeant sur votre VPS, vous gardez 100 % de vos abonnés payants (hors frais Stripe), vous personnalisez le thème sans restriction, et vous maîtrisez votre liste d'emails — votre actif le plus précieux. Avec Ghost v6, les créateurs qui monétisent leurs newsletters bénéficient aussi de la collecte automatique de la TVA via Stripe Tax, sans aucune dépendance à un service tiers.
Les bénéfices d'un Ghost auto-hébergé
- Aucune commission plateforme sur vos abonnements payants (hors Stripe)
- Performances natives : le temps de chargement se mesure depuis la connexion du lecteur — il dépend de l'opérateur, de l'heure et du chemin emprunté
- Newsletters et membres intégrés, sans empilement de plugins
- Personnalisation totale du thème Handlebars et accès complet à l'API
- Maîtrise de votre liste d'abonnés et de vos données
- Coût fixe du VPS quel que soit le nombre de lecteurs
- Ghost v6 : collecte TVA/taxe intégrée via Stripe Tax pour les créateurs monétisés
Prérequis réalistes
Ghost v6 tourne sur Node.js 20 LTS minimum (Node 22 recommandé pour les performances). Prévoyez un VPS avec au moins 1 vCPU et 2 Go de RAM pour un blog avec un trafic confortable ; montez à 4 Go si votre audience grandit vite ou si vous activez les newsletters volumineuses. Pour un usage de production, réservez 20 Go de disque minimum pour les médias et la base de données.
La base de données recommandée en production est MySQL 8 (SQLite n'est supporté qu'en développement — voir la section dépannage). Il vous faut aussi un service SMTP transactionnel (Mailgun, Postmark, Brevo) pour l'envoi fiable des newsletters et des emails d'authentification des membres, un domaine blog.votredomaine.com pointé sur l'IP de votre VPS, et Caddy ou Nginx pour le reverse proxy HTTPS. Caddy est préférable : il provisionne et renouvelle les certificats Let's Encrypt sans configuration supplémentaire.
Installation via Ghost CLI (méthode recommandée)
Préparer le serveur
Sur Debian/Ubuntu, installez Node.js 20, MySQL 8, Nginx (requis par Ghost CLI pour sa vérification de compatibilité) et Caddy. Créez un utilisateur dédié (pas root) :
add user --disabled-login ghost-user
su - ghost-userInstaller Ghost CLI
npm install ghost-cli@latest -gGhost CLI gère l'installation, les migrations de base, les mises à jour et les redémarrages du process manager PM2.
Créer le répertoire et lancer l'installation
mkdir -p /var/www/ghost
cd /var/www/ghost
ghost installLe wizard vous demande l'URL du blog (ex. https://blog.votredomaine.com), les identifiants MySQL, le service SMTP et si vous souhaitez configurer Nginx. Répondez non à la config Nginx si vous utilisez Caddy — vous la configurerez à l'étape suivante.
Configurer le reverse proxy TLS avec Caddy
Créez ou éditez votre Caddyfile :
blog.votredomaine.com {
reverse_proxy localhost:2368
encode gzip
header /ghost/* Cache-Control "no-store"
header /members/* Cache-Control "no-store"
}Caddy obtient et renouvelle le certificat Let's Encrypt automatiquement. Ghost écoute en local sur le port 2368 ; seul Caddy est exposé sur les ports 80 et 443.
Sécuriser le premier accès
Ouvrez /ghost immédiatement après l'installation : Ghost affiche son assistant de création de compte (nom, e-mail, mot de passe). Complétez-le sans délai — tant que l'assistant n'est pas finalisé, quiconque atteint cette URL peut devenir propriétaire du blog.
Connecter votre service SMTP
Dans Paramètres → Email, vérifiez que les identifiants SMTP sont corrects et envoyez un email de test. L'envoi de newsletters et les emails de connexion des membres passent par cette configuration — un MAIL_FROM mal formé (sans domaine vérifié) est l'une des causes les plus fréquentes de silences à l'inscription.
Brancher Stripe et activer les abonnements
Dans Paramètres → Membres, connectez votre compte Stripe pour activer les abonnements payants. Définissez vos niveaux (tiers), vos prix mensuels et annuels, puis publiez votre premier article et envoyez votre première newsletter.
Lancer Caddy et vérifier le reverse proxy
Une fois le Caddyfile écrit, démarrez ou rechargez Caddy pour appliquer la configuration :
caddy run --config /etc/caddy/CaddyfileSi Caddy est géré en tant que service systemd (ce qui est le cas après une installation via APT), préférez la commande de rechargement sans interruption :
systemctl reload caddyCaddy contacte immédiatement Let's Encrypt pour obtenir un certificat TLS pour votre domaine via le challenge HTTP-01. Dans les 30 secondes, https://blog.votredomaine.com doit répondre. Vérifiez l'état du certificat :
curl -sv https://blog.votredomaine.com/ 2>&1 | grep -E 'SSL|subject|issuer'Si la commande affiche un issuer: O=Let's Encrypt, le certificat est valide. En cas d'erreur connection refused, vérifiez que Ghost tourne bien sur le port 2368 avec ghost status depuis le répertoire d'installation. Si le port 443 est fermé dans votre pare-feu, ouvrez-le avant de lancer Caddy : ufw allow 443.
Ghost v6 et Stripe Tax : le nouveau champ tax_id_collection
Ghost v6 introduit la prise en charge du champ tax_id_collection de l'API Stripe. Ce champ permet à Stripe Tax de collecter automatiquement le numéro de TVA ou d'identification fiscale de l'acheteur au moment du paiement, conformément aux réglementations européennes et mondiales.
Pour les instances existantes migrées vers Ghost v6, cette fonctionnalité est une configuration de votre côté Stripe, pas un changement dans Ghost lui-même. Deux points à vérifier :
1. Dans le Dashboard Stripe, activez Stripe Tax et configurez vos règles fiscales par pays.
2. Dans Stripe → Checkout → Paramètres, activez la collecte du numéro fiscal si requis pour votre marché.
Les instances Ghost v5 qui mettent à jour vers v6 sans ajuster leurs paramètres Stripe continueront à fonctionner, mais les nouvelles fonctions de conformité fiscale resteront inactives tant que vous n'aurez pas configuré Stripe Tax de votre côté.
Mettre à jour Ghost avec Ghost CLI
Ghost CLI simplifie les mises à jour majeures et mineures. Depuis le répertoire d'installation :
cd /var/www/ghost
ghost updatePour cibler une version spécifique, par exemple lors d'une migration v5 → v6 :
ghost update 6.x.xGhost CLI arrête le process PM2, applique les migrations de base de données, met à jour les fichiers et redémarre Ghost. Si une migration échoue, Ghost CLI effectue un rollback automatique et affiche le détail de l'erreur dans le terminal.
Avant toute mise à jour majeure (v5 → v6), deux gestes préventifs sont indispensables : sauvegardez le répertoire de contenu /var/www/ghost/content (médias et thèmes personnalisés) et exportez la base MySQL :
mysqldump -u ghost -p ghost_db > ghost_backup_$(date +%F).sqlEnfin, vérifiez la version installée après la mise à jour :
ghost versionUn numéro de version incorrect après une mise à jour signale généralement un problème de permissions sur le répertoire /var/www/ghost — vérifiez que l'utilisateur dédié est bien propriétaire du dossier.
Dépannage : les erreurs de démarrage fréquentes
Ghost démarre mais retourne une page blanche ou une erreur 500
Vérifiez les logs avec ghost log. La cause la plus fréquente est une valeur url incorrecte dans config.production.json — Ghost génère tous ses liens internes à partir de cette valeur, et une URL en HTTP alors que Caddy sert en HTTPS provoque des boucles de redirection.
Erreur « ER_NOT_SUPPORTED_AUTH_MODE » au démarrage
Ghost v6 requiert MySQL 8 avec le plugin d'authentification mysql_native_password. Si votre MySQL est configuré en caching_sha2_password par défaut, modifiez l'utilisateur :
ALTER USER 'ghost'@'localhost' IDENTIFIED WITH mysql_native_password BY 'votre_mot_de_passe';
FLUSH PRIVILEGES;SQLite en production : pourquoi ce n'est pas une option
Ghost accepte SQLite en mode développement, mais ce moteur n'est pas supporté en production : il ne gère pas les accès concurrents, et les newsletters volumineuses ou les pics de trafic provoquent des verrous de base irréversibles. Migrez vers MySQL avant de mettre votre instance en ligne.
L'upload de thème échoue en production
Ghost limite la taille des uploads de thèmes. Si l'upload échoue en silence ou retourne une erreur 413, ajustez la limite côté Caddy :
blog.votredomaine.com {
request_body {
max_size 50MB
}
reverse_proxy localhost:2368
}MAIL_FROM mal configuré : membres qui ne reçoivent pas d'email
Le champ mail.from dans config.production.json doit porter une adresse dont le domaine est vérifié chez votre fournisseur SMTP (enregistrements SPF, DKIM actifs). Un domaine non vérifié aboutit à des silences à l'inscription ou à des rejets SMTP que Ghost signale rarement clairement dans ses logs.
Placez Cloudflare en proxy devant Caddy pour absorber les pics de trafic (effet Hacker News ou réseaux sociaux) : presque tout le contenu public de Ghost est statique et se cache très bien. Excluez /ghost/, /members/ et /api/ du cache par des règles de page ou une règle de cache personnalisée — ces routes doivent toujours atteindre Ghost en direct pour que l'authentification des membres et l'admin fonctionnent correctement.
Sauvegardes automatiques
Le contenu dynamique de Ghost (médias, thèmes personnalisés) vit dans /var/www/ghost/content. Ajoutez un cron qui sauvegarde ce répertoire et un export MySQL quotidien vers un stockage distant. Ghost CLI ne sauvegarde pas automatiquement.
# Export MySQL quotidien — à placer dans crontab
0 2 * * * mysqldump -u ghost -p ghost_db | gzip > /backups/ghost-$(date +%F).sql.gzLa documentation officielle
Pour la configuration avancée et les options propres à l'outil, référez-vous à la documentation officielle de Ghost. Ce guide couvre la mise en ligne sur VPS ; la doc éditeur reste la référence pour les réglages fins, les mises à jour majeures et les cas d'usage spécifiques.