J'utilise sur mon serveur dédié, un blog qui utilise le CMS "ghost". Lui même nécessite une base de données MySQL et forcément pour mettre en ligne le tout, j'utilise Traefik.
Nous allons voir un cas pratique de déploiement d'un blog avec ces 3 technologies. Au programme :
- Création du fichier docker-compose pour créer ma stack,
- Publier ma stack avec Traefik.
Pré-requis
Forcément l'installation de Docker sur mon serveur dédié, et également docker-compose.
Vous pouvez également sécuriser votre serveur avec quelques règles IPTABLES.
Mais comme vous suivez ce blog régulièrement, vous êtes prêts ! Moi aussi ...
Création de notre stack
Afin de réaliser une telle installation, le premier élément à vérifier est tout simplement la documentation du service que l'on souhaite publier.
Dans notre cas : Ghost. Un rapide tour sur la documentation de l'image docker présente sur le hub vous permettra de récupérer un fichier de stack :
# by default, the Ghost image will use SQLite (and thus requires no separate database container)
# we have used MySQL here merely for demonstration purposes (especially environment-variable-based configuration)
version: '3.1'
services:
ghost:
image: ghost:1-alpine
restart: always
ports:
- 8080:2368
environment:
# see https://docs.ghost.org/docs/config#section-running-ghost-with-config-env-variables
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: example
database__connection__database: ghost
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
Ce fichier est un bon point de départ. Je vais apporter quelques modifications à ce fichier afin de réaliser les opérations suivantes :
- Ajouter notre routeur edge : Traefik
- Retirer le NAT 8080 vers 2368
- Créer les labels nécessaires à Traefik pour publier notre blog
Traefik
Ajoutons donc la déclaration de Traefik au précédent fichier. J'en profite pour passer le fichier en version 3.7 ( il s'agit de la version de docker-compose. Dans ce cas présent, cela ne change pas grand chose mais autant utiliser la dernière syntaxe en date ... ) :
version: '3.7'
services:
reverse-proxy:
image: traefik:2.1
restart: always
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/etc/traefik/traefik.yml:ro
Je vais laisser pour cet article le dashboard accessible à tous ( le port 8080 ). ⚠️ Si vous souhaitez mettre cette stack sur une IP publique, retirez le ou pensez à restreindre l'accès par IP à cette ressource ou par authentification ! ⚠️
J'utilise dans cette stack un fichier YAML
que nous avons déjà vu :
api:
insecure: true
providers:
docker:
exposedByDefault: false
entryPoints:
http:
address: :80
Configuration de Ghost
À ce stade vous pouvez déjà déployer Traefik afin de vous assurer qu'aucune erreur ne soit présente :
docker-compose up -d reverse-proxy
Ajoutons maintenant les labels nécessaires à Ghost :
version: '3.7'
services:
reverse-proxy:
image: traefik:2.1
restart: always
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/etc/traefik/traefik.yml:ro
ghost:
image: ghost:3
restart: always
environment:
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: example
database__connection__database: ghost
url: http://ghost.docker.localhost/
labels:
- "traefik.enable=true"
- "traefik.http.services.monblog.loadbalancer.server.port=2368"
- "traefik.http.routers.monblog.rule=Host(`ghost.docker.localhost`)"
- "traefik.http.routers.monblog.entrypoints=http"
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
Pensez à ajouter ghost.docker.localhost
à votre fichier hosts et vous pouvez lancer votre stack :
docker-compose up -d
À ce stade, tout fonctionne. Mais il faut être honnête pour une éventuelle mise en production, il manque quelques éléments !
5, 4, 3, 2, 1 ... 🚀
Pour la mise en production, voici quelques éléments qu'il nous faut modifier ou ajouter :
- Des volumes pour les données persistentes.
- Créer des réseaux pour nos containeurs.
- Et bien sûr ... Changer les mots de passes :)
Modifions notre fichier docker-compose afin d'ajouter tout ça !
Quelles données devons-nous rendre persistantes ? La documentation de Ghost nous donne l'information : /var/lib/ghost/content
. Mais il faut également penser à un volume pour les données MySQL.
Enfin afin de faire communiquer Traefik et Ghost, je vais mettre en place un réseau entre ces deux containeurs. Et un second réseau pour Ghost et MySQL afin de limiter leur communication dans ce réseau.
Dernier détail, je donne un nom fixe à mes containeurs pour faciliter l'accès au log par exemple :
version: '3.7'
services:
reverse-proxy:
image: traefik:2.1
restart: always
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.yml:/etc/traefik/traefik.yml:ro
networks:
- traefik
container_name: traefik
ghost:
image: ghost:3
restart: always
environment:
database__client: mysql
database__connection__host: db
database__connection__user: ghost
database__connection__password: motdepasseutilisateurghost
database__connection__database: ghost
url: http://ghost.docker.localhost/
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik"
- "traefik.http.services.monblog.loadbalancer.server.port=2368"
- "traefik.http.routers.monblog.rule=Host(`ghost.docker.localhost`)"
- "traefik.http.routers.monblog.entrypoints=http"
volumes:
- www-data:/var/lib/ghost/content
networks:
- traefik
- lan
container_name: ghost
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: motdepasseutilisateurroot
MYSQL_USER: ghost
MYSQL_DATABASE: ghost
MYSQL_PASSWORD: motdepasseutilisateurghost
volumes:
- mysql-data:/var/lib/mysql
networks:
- lan
container_name: mysql
volumes:
mysql-data:
name: mysql-data
www-data:
name: www-data
networks:
lan:
name: lan
traefik:
name: traefik
Un petit up
de votre stack et rendez-vous sur : http://ghost.docker.localhost !
Dans un prochain article, nous verrons comment ajouter le HTTPS à notre blog avec un certificat obtenant A ou A+ sur https://www.ssllabs.com. Ainsi que quelques règles de filtrage : Comme par exemple, limiter l'accès au répertoire /ghost par IP. On ajoutera également quelques headers de securité afin d'obtenir un bon score sur https://securityheaders.com/.
Liens utiles :
- https://github.com/lfache/deployer-ghost-avec-traefik : Voici les fichiers de configurations sur Github !