Parce qu'il y a toujours une solution...

Le but de cette documentation est de vous fournir un fichier .yml clé en main pour installer le CMS Ghost derrière Traefik.


Article mis à jour suite aux commentaires de ldez oncernant un soucis de configuration côté Traefik (mélange entre conf' statique et dynamique) 😉 (merci !!)

Ghost est un CMS pour propulser des sites web type "blog", un peu comme ComputerZ Solutions ;). Cet outil nécessite une base de données dans laquelle y seront stockées toutes les données (pages, posts et configurations). J'utilise Traefik en frontal de Ghost - plus de détails à cette adresse (CZS).

Quelques pré-requis avant de se lancer : avoir Docker (pour Ubuntu ou CentOS 7) et docker-compose installé sur votre machine.

Sans plus attendre, voici le fichier docker-compose.yml :

version: '3.7'
services:
  traefik:
    image: traefik:chevrotin
    restart: always
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - traefik.toml:/etc/traefik/traefik.toml:ro
      - acme.json:/acme.json
    networks:
      - oueb

  sqlghost:
    image: mariadb:bionic
    restart: always
    command: --sql-mode=""
    volumes:
      - datasqlghost:/var/lib/mysql
    networks:
      - oueb
    environment:
      - "MYSQL_ROOT_PASSWORD=secretpasswordROOTsql"
      - "MYSQL_USER=ghost"
      - "MYSQL_PASSWORD=sqlghostuserpassword"
      - "MYSQL_DATABASE=ghost"
      - "MYSQL_ROOT_HOST=%"
      - "MYSQL_USER_HOST=%"
    labels:
      - traefik.enable=false

  webghost:
    image: ghost:3
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - dataghost:/var/lib/ghost/content
      - config.production.json:/var/lib/ghost/config.production.json
    networks:
      - oueb
    depends_on:
      - sqlghost
    labels:
      - traefik.enable=true
      - traefik.docker.network=oueb
      - traefik.http.routers.ghost.entrypoints=insecure, secure
      - traefik.http.routers.ghost.rule=Host(`blog.nomdedomaine.org`)
      - traefik.http.routers.ghost.tls=true
      - traefik.http.routers.ghost.tls.certresolver=letsencrypt

networks:
  oueb:
    external: true

volumes:
  datasqlghost:
  dataghost:
docker-compose.yml

Les lignes sont explicites : Création du service "traefik" pour le conteneur reverse-proxy, le service "sqlghost" à base de MariaDB et le service "webghost" pour le CMS Ghost. Seul Ghost a des labels correspondant pour Traefik - avec ces quelques lignes, votre Ghost sera "routable" vers le web et automatiquement géré en SSL.
Vous remarquerez aussi des volumes complémentaires comme "/etc/timezone" et "/etc/localtime" - utilisé pour être en relation avec le serveur hôte (qui est à l'heure via NTP) et donc avoir un horodatage cohérent. Les fichiers de configurations sont à côté du docker-compose.yml, libre à vous de les placer ailleurs (et de modifier le chemin dans la conf)

Les labels Traefik mis en place dans ce fichier docker-compose.yml sont dit en "configuration statique".


Avant de lancer les conteneurs, vous devez encore créer deux fichiers, notamment un pour Traefik :

[global]
  sendAnonymousUsage = false

[log]
  level = "WARNING"

[providers]
  [providers.docker]
    endpoint = "unix:///var/run/docker.sock"
    watch = true
    exposedByDefault = true
    swarmMode = false

[entryPoints]
  [entryPoints.insecure]
  address = ":80"

  [entryPoints.secure]
  address = ":443"

[certificatesResolvers.letsencrypt.acme]
  email = "mail@nom-de-domaine.fr"
  storage = "acme.json"
  caServer = "https://acme-v02.api.letsencrypt.org/directory"
  keyType = "EC256"
  [certificatesResolvers.letsencrypt.acme.httpChallenge]
    entryPoint = "http"
traefik.toml

Le fichier de configuration Traefik se décompose sous forme de blocs - tout est assez explicite, je ne vais pas faire une description pour chaque ligne.


Ghost a aussi besoin d'un fichier de configuration pour être exploitable. Suivez bien le formalisme du fichier .json requis - ci-dessous un exemple de conf' :

{
  "url": "https://blog.nomdedomaine.org",
  "server": {
    "port": 2368,
    "host": "0.0.0.0"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "sqlghost",
      "user": "ghost",
      "port": "3306",
      "password": "sqlghostuserpassword",
      "database": "ghost"
    }
  },
  "transports": ["stdout", "file"]
  },
  "privacy": {
    "useUpdateCheck": false,
    "useGravatar": false,
    "useRpcPing": false,
    "useStructuredData": true
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/lib/ghost/content"
  }
}
config.production.json

Maintenant que vos fichiers sont créés, vous pouvez initier un "docker-compose up -d" et voir la magie s'opérer... :) Le site web sous Ghost sera accessible au nom de domaine stipulé dans la conf', Traefik effectuera automatiquement le lien/la redirection et le tout avec du HTTPS via Let's Encrypt.