Infrastructure : Déploiement de Ghost via Docker Compose
La fiabilité d'une plateforme de contenu repose sur la simplicité et la reproductibilité de son environnement. Chez MADSAAS, nous avons fait le choix d'orchestrer notre instance Ghost via Docker Compose pour garantir une mise en production rapide, maintenable et sécurisée.
Déployer Ghost via Docker Compose n'est pas seulement une question de commodité, c'est une stratégie d'ingénierie moderne. Cela nous permet d'isoler les services, de gérer la persistance des données de manière déclarative et de garantir la cohérence entre nos environnements de développement et de production.
Notre approche Docker Compose
Nous utilisons une stack complète comprenant Ghost (Alpine Linux) et MySQL 8.0, orchestrés via un fichier unique qui définit l'ensemble de notre infrastructure applicative.
Voici le docker-compose.yml que nous utilisons pour propulser ce site :
version: "3.8"
services:
ghost:
image: ghost:5-alpine
container_name: ${DOCKER_APP_NAME}
restart: unless-stopped
ports:
- "2371:2368"
environment:
url: ${GHOST_URL}
database__client: mysql
database__connection__host: ${MYSQL_HOST}
database__connection__user: ${MYSQL_USER}
database__connection__password: ${MYSQL_PASSWORD}
database__connection__database: ${MYSQL_DATABASE}
NODE_ENV: ${NODE_ENV}
volumes:
# Theme mount — hot reload on restart
- ./madsaas-theme:/var/lib/ghost/content/themes/madsaas-theme
# Persist content (images, data, etc.)
- ghost_content_madsaas:/var/lib/ghost/content
depends_on:
db:
condition: service_healthy
db:
image: mysql:8.0
container_name: ${DOCKER_DB_NAME}
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ghost_db_madsaas:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
volumes:
ghost_content_madsaas:
ghost_db_madsaas:
Configuration des variables d'environnement
Pour sécuriser et centraliser notre configuration, nous utilisons un fichier .env à la racine du projet :
# Application
DOCKER_APP_NAME=ghost-madsaas
DOCKER_DB_NAME=ghost-db-madsaas
NODE_ENV=production
# Ghost Configuration
GHOST_URL=https://votre-domaine.fr
# MySQL Configuration
MYSQL_HOST=db
MYSQL_DATABASE=ghost_prod
MYSQL_USER=ghost_user
MYSQL_PASSWORD=VotreMotDePasseSecurise123!
MYSQL_ROOT_PASSWORD=VotreRootPasswordSecurise456!
Pourquoi cette architecture ?
Séparation des responsabilités
Chaque service a un rôle bien défini. Ghost gère l'application web tandis que MySQL assure la persistance des données. Cette séparation permet de scaler ou de maintenir chaque composant indépendamment.
Gestion intelligente des volumes
Nous utilisons deux types de volumes pour optimiser flexibilité et performance :
Volume nommé (ghost_content_madsaas) pour la persistance générale du contenu. Docker gère automatiquement l'emplacement et les permissions, garantissant une portabilité maximale entre environnements.
Bind mount (./madsaas-theme) pour notre thème personnalisé. Cette approche permet un développement en temps réel : toute modification du thème est immédiatement disponible après redémarrage du conteneur, sans reconstruction d'image.
Health checks et dépendances
La directive depends_on avec condition service_healthy garantit que Ghost ne démarre qu'une fois MySQL opérationnel. Le healthcheck MySQL vérifie activement la disponibilité de la base toutes les 10 secondes, éliminant les erreurs de connexion au démarrage.
Sécurité par l'environnement
Toutes les informations sensibles sont externalisées dans le fichier .env, jamais versionnées dans Git. En production, ces variables sont injectées via le système de secrets de notre orchestrateur ou via des variables d'environnement système.
Politique de redémarrage
La directive restart: unless-stopped assure la résilience : en cas de crash applicatif ou de redémarrage serveur, les conteneurs redémarrent automatiquement, garantissant une disponibilité maximale sans intervention manuelle.
Déploiement et maintenance
Le déploiement devient trivial avec cette approche :
# Premier déploiement
docker compose up -d
# Mise à jour de Ghost
docker compose pull ghost
docker compose up -d --no-deps ghost
# Consultation des logs
docker compose logs -f ghost
# Backup de la base de données
docker compose exec db mysqldump -u root -p${MYSQL_ROOT_PASSWORD} ${MYSQL_DATABASE} > backup.sql
Scalabilité et reverse-proxy
En production, ce stack est couplé à Traefik ou Nginx comme reverse-proxy, gérant nativement le SSL via Let's Encrypt, la compression Gzip et le load balancing si nécessaire. Le port 2371 n'est alors accessible que depuis le réseau interne Docker.
Cette rigueur dans notre propre infrastructure est la même que celle que nous appliquons aux projets SaaS de nos clients : reproductible, maintenable et évolutive.