1. Le but
Le but est d'avoir plusieurs blogs accessibles chacun par un sous domaine dédié hébergé par un ou plusieurs multiblog Dotclear. Ou autrement dit, si on tape https://blog.mondomaine.tld
dans notre navigateur, il affiche notre blog.
Pour cela on va avoir besoin :
- accéder à la gestion de nos noms de domaines pour les rediriger vers notre serveur
- une application qui va gérer la distribution des sous domaines
- une application qui va héberger les blogs
- une application qui va héberger les bases de données.
En réalité Docker va nous simplifier la chose car on va pouvoir lancer toutes les applications à partir d'un seul fichier de configuration.
On continue donc de préciser ce qu'il va falloir :
- Pour la gestion des domaines, on laisse ça à notre registrar (J'utilise souvent OVH)
- Pour la distribution des sous domaines et des certificats, on va utiliser Nginx Proxy Manager
- Pour les blog, ben ça sera Dotclear hein
- Pour les bases de données, ce sera Mariadb
On va même compliquer la chose en ajoutant un second multiblog Dotclear pour d'éventuels tests.
2. Le serveur
Détail qui n'en est pas un, votre serveur doit être accessible depuis les internets ! Par exemple les blogs dotclear.watch sont hébergés sur des serveurs privés virtuels (VPS) chez OVH. Vous pouvez bien entendu héberger chez vous avec peut-être des DNS dynamiques mais ce n'est pas le but de cet article. On part du principe ici que la machine sera prête, c'est à dire qu'un système sera installé avec les principaux outils et qu'un pare-feu sera opérationnel. Dans mon cas, OVH me facilite la tâche en proposant un système Debian avec Docker préconfiguré, mais pas le pare-feu et autre fail2ban. Encore une fois ce n'est pas le but de cet article.
Donc On aura besoin d'avoir les ports suivant ouverts :
- SSH, en TCP, par défaut port
22
mais un autre peut être configuré, - NPM, en TCP, par défaut port
81
, accès au proxy manager, mais on va changer ce port - HTTP, en TCP, port
80
, accès web - HTTPS, en TCP, port
443
, accès web sécurisé - ICMP, en UDP, port
53
, normalement la machine reste ouverte en UDP pour l'ICMP
Coté logiciels :
- L'environnement Docker (avec docker compose) doit être installé et l'utilisateur courant doit avoir les droits dessus. (Il existe de nombreux tuto sur le web pour ça)
- un éditeur de texte (comme par exemple nano)
3. Gestion des sous domaines
Quand vous tapez une adresse web dans le navigateur, derrière ça il y a quelqu'un qui dit que telle adresse doit renvoyer vers telle machine, et on utilise les adresses IP pour cela, c'est la Zone DNS. Ce quelqu'un est ce qu'on appelle un registrar, il y en a des milliers et vous pouvez même être votre propre registrar.
On va partir du principe qu'on est l'heureux propriétaire du nom de domaine mondomaine.tdl
et donc il va va falloir créer des zones DNS pour nos sous domaines. On va en créer 3 :
blog.mondomaine.tld
perso.mondomaine.tld
test.mondomaine.tld
Les deux premiers iront sur le multiblog de production et le dernier sur celui de test mais on en est pas là.
Suivant votre registrar, il peut avoir des outils simplifiés pour modifier la Zone DNS, on simplement une modification en mode texte. Dans tous les cas il va falloir dire que ces 3 sous domaines pointent vers la machine qui va héberger nos blogs. Il y a deux champs à modifier :
- Le champs A qui correspond à l'IPv4 de notre machine
- Le champs AAAA qui correspond à l'IPv6 de notre machine
Si notre machine a comme IP 1.2.3.4 et 2001:1234:5678::abcd, la partie correspondante du fichier DNS donnera :
blog IN A 1.2.3.4
blog IN AAAA 2001:1234:5678::abcd
perso IN A 1.2.3.4
perso IN AAAA 2001:1234:5678::abcd
test IN A 1.2.3.4
test IN AAAA 2001:1234:5678::abcd
Dans le manager d'OVH l'outil ressemble à ça :
Voilà, nos sous-domaines arrive jusqu'à notre machine, maintenant il va falloir les attraper et les distribuer.
4. Distribution des sous-domaines
On va utiliser un serveur proxy en entrée de notre machine pour redistribuer les sous-domaines vers nos blogs. Ce sera Nginx Prox Manager qu'on lancera dans un container Docker à l'aide de Docker compose.
On se connect en SSH à notre machine, on créé un premier répertoire nommé npm
qui servira de volume persistant à notre container et on édite le fichier docker-compose.yml
:
mkdir npm
nano docker-compose.yml
Puis on y configure notre premier container :
networks:
default:
name: npm
services:
# Nginx proxy manager
npmapp:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
container_name: npmapp
ports:
- 80:80
- 443:443
- 61345:81
volumes:
- ./npm/data:/data
- ./npm/letsencrypt:/etc/letsencrypt
healthcheck:
test: ["CMD", "/usr/bin/check-health"]
interval: 10s
timeout: 3s
Ici le service sera nommé npmapp
, il créera un container nommé npmapp
basé sur l'image jc21/nginx-proxy-manager:latest
, le container écoutera sur les ports 61345,80,443
, il utilisera deux volumes persistant npm/data
et npm/letsencrypt
. Un réseau nommé npm
sera créer qui permettra aux containers de se parler en utilisant leurs noms.
On exécute la composition avec :
docker compose up -d
On attend un peu que l'image soit téléchargé et que les containers soient démarrés, puis dans notre navigateur web on se connecte à l'adresse IP de notre serveur sur le port 61345 : http://1.2.3.4:61345
, d'origine c'est le port 81 mais on l'a changé dans le fichier de configuration et on a ouvert le port du pare-feu.
La page de login de NPM s'affiche, lors de la première connexion l'utilisateur est admin@exemple.com
et le mot de passe changeme
une fois connecter il va demander de créer un utilisateur et un mot de passe. Utilisez un mot de passe complexe.
On commence par créer des cetificats SSL pour nos sous domaines, cela permet d'avoir des adresses en https. Pour cela on va dans l'onglet SSL Certificates, on clique le bouton Add SSL Certificate, on ajoute nos deux premiers sous domaines, on ajoute notre adresse mail (valide si possible) puis pour la vérification on utilise la méthode qu'on préfère. Personnellement j'ai accès aux API de mes registrar donc j'utilise le DNS Challenge. On accepte les termes et on sauve en cliquant Save. Le processus va mouliner un petit moment puis le certificat sera créé.
Maintenant on va pouvoir enfin rediriger nos sous domaines vers notre futur multiblog. Pour cela, dans l'onglet Hosts -> Proxy Hosts, on clique sur Add Proxy Host, une fenêtre de configuration s'ouvre.
On configure comme suis :
- Détails -> Domain Names : nos deux noms de sous domaines
- Détails -> Scheme : http
- Détails -> Forward Hostname : dcstableapp (le nom du futur container Docker)
- Détails -> Forward Port : 80
- SSL -> SSL Certiicate : on sélectionne le certificat qu'on a créée précédemment
- SSL -> Force SSL : coché
- SSL -> HTTP/2 : coché
- SSL -> HSTS : coché
Puis on clique sur Save.
On recrée un autre certificat SSL et un autre Proxy Host pour notre troisième sous domaine, car il ira sur un autre container. La seule différence dans la configuration sera le Forward Hostname qu'on mettra à dcunstableapp
, qui sera notre container de test.
Voila nos redirections sous configurées.
5. Les containers de blog
Le container hébergeant nos deux premiers blogs sera basé sur la version stable Doclear et utilisera une base de donnée Mysql.
On retourne dans notre terminal SSH et on creé le répertoire du volume persistant et on modifie le fichier docker-compose.yml
qu'on a créé un peu plus tôt.
mkdir dcstable
nano docker-compose.yml
On ajoute les deux services Dotclear et MariaDB :
networks:
default:
name: npm
services:
# Nginx proxy manager
npmapp:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
container_name: npmapp
ports:
- 80:80
- 443:443
- 81:81
volumes:
- ./npm/data:/data
- ./npm/letsencrypt:/etc/letsencrypt
healthcheck:
test: ["CMD", "/usr/bin/check-health"]
interval: 10s
timeout: 3s
# Mariadb database
dcstabledb:
image: mariadb:latest
container_name: dcstabledb
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
volumes:
- ./dcstable/db:/var/lib/mysql
depends_on:
npmapp:
condition: service_healthy
environment:
MYSQL_ROOT_PASSWORD: dotclear_root
MYSQL_DATABASE: dotclear_db
MYSQL_USER: dotclear_user
MYSQL_PASSWORD: dotclear_pwd
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
# Doclear web application
dcstableapp:
image: jcpd/docker-dotclear:latest
container_name: dcstableapp
restart: unless-stopped
volumes:
- ./dcstable/app:/var/www/dotclear
depends_on:
dcstabledb:
condition: service_healthy
environment:
DC_DBDRIVER: mysqlimb4
DC_DBHOST: dcstabledb
DC_DBNAME: dotclear_db
DC_DBUSER: dotclear_user
DC_DBPASSWORD: dotclear_pwd
DC_DBPREFIX: dc_
DC_ADMINMAILFROM: contact@exemple.com
Ne pas oublier de remplacer dotclear_root, dotclear_user et dotclear_pwd par des valeurs personnelles !
On voit que les 3 services sont configurés depuis le même fichier, c'est pratique ! Et une astuce ici est d'attendre qu'un service soit fonctionnel pour démarrer le suivant, on commence par le Proxy puis la base de données et enfin le serveur web, grâce à la directive depends_on.
On exécute la composition avec :
docker compose up -d
Et on attend que tous les services soient fonctionnels puis dans notre navigateur web on entre l'adresse du premier blog http://blog.mondomaine.tld
la phase finale de configuration de Dotclear devrait apparaitre.
On rentre les informations de notre utilisateur super admin, on valide deux fois et on arrive dans l'interface d'administration du multiblog.
Par défaut les images Docker de Dotclear sont configurées pour fonctionner en local en sous-répertoire, car elles ont été pensé pour simplement tester Dotclear dans son coin, chez soi. Mais nous travaillons dans notre exemple, à distance en sous-domaine. Il va donc falloir faire quelques ajustements.
Le premier changement est que nous travaillons avec des certificats SSL en https, il faut modifier l'adresse de l'administration de Dotclear dans son fichier de configuration, pour cela dans le terminal SSH on édite le fichier config.php
:
nano dcstable/app/config.php
On cherche la ligne :
// Admin URL. You need to set it for some features.
define('DC_ADMIN_URL','http://blog.mondomaine.tld/admin/');
Qu'on remplace par :
// Admin URL. You need to set it for some features.
define('DC_ADMIN_URL','https://blog.mondomaine.tld/admin/');
La différence ? On a ajouté le S à http. On enregistre et on retourne dans l'interface web d'administration.
Le premier blog est configuré par le script d'installation de Dotclear pour être en sous répertoire, il faut donc modifier la façon dont Dotclear va gérer certaines URLs.
On parcourt les menus Blog -> Paramètres du blog -> Paramètres avancés du blog
( https://blog.mondomaine.tld/admin/index.php?process=BlogPref#advanced-pref )
et on modifie Url du blog de http://blog.mondomaine.tld/default/
à https://blog.mondomaine.tld/
. Et on valide.
Ensuite on parcourt les menus Réglages système -> about:config -> system
( https://blog.mondomaine.tld/admin/index.php?process=Plugin&p=aboutConfig#l_system )
et on modifie l'entrée public_url de /default/public
à /public
. et on valide.
Le premier blog créer par le script d'installation de Dotclear porte l'ID default
, la configuration d'origine des images Docker va rediriger le sous domaine nommé blog
vers l'ID default
, si le sous domaine du premier blog n'est pas nommé blog
, il faudra aussi modifier le fichier de configuration de Nginx :
nano dcstable/app/servers/subdomain.conf
Et modifier :
# Redirect a particular subdomain
if ($dc_blog_id = 'blog') {
set $dc_blog_id default;
}
en remplaçant par le sous domaine de votre premier blog :
# Redirect a particular subdomain
if ($dc_blog_id = 'plop') {
set $dc_blog_id default;
}
Voilà, notre premier blog est prêt.
On va maintenant créer notre second blog. Pour cela on parcourt les menus Réglages système -> Blogs -> Créer un nouveau blog et on remplie le formulaire. L'identifiant sera le sous domaine perso
, le nom du blog sera ce que vous voulez, et l'URL sera https://perso.mondomaine.tld/
(ne pas oublier le / à la fin ! ). On valide. Voila notre second blog est prêt, rien d'autre à faire.
Vous aurez compris la démarche pour ajouter autant de blog que vous voulez à votre multiblog.
Créer la Zone DNS, créer un Certificat SSL, créer un Proxy Host, créer un blog.
6. Le blog de test
On aurait pu s'arrêter là mais comme on est gourmand on va ajouter un multiblog de test à notre installation, vous vous rappelez au début on a configuré 3 sous domaines chez notre registrar, il nous reste donc à utiliser le troisième test.mondomaine.tld
.
Les premières étapes sont identiques, si on ne les a pas fait au début, on créé un certificat pour ce sous domaine, on créé un Proxy Host qui aura comme Forward Hostname le nom du futur container dcsunstableapp
, le reste est identique à ce qu'on à fait précédemment.
Ensuite on va ajouter notre container de test, on va dans le terminal SSH et on ajoute le dossier pour le volume persistant et on édite le fichier de docker-compose.yml
:
mkdir dcunstable
nano docker-compose.yml
On complète notre composition en ajoutant à la fin notre dernier container pour le multiblog de test :
networks:
default:
name: npm
services:
# Nginx proxy manager
npmapp:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
container_name: npmapp
ports:
- 80:80
- 443:443
- 81:81
volumes:
- ./npm/data:/data
- ./npm/letsencrypt:/etc/letsencrypt
healthcheck:
test: ["CMD", "/usr/bin/check-health"]
interval: 10s
timeout: 3s
# Mariadb database
dcstabledb:
image: mariadb:latest
container_name: dcstabledb
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
volumes:
- ./dcstable/db:/var/lib/mysql
depends_on:
npmapp:
condition: service_healthy
environment:
MYSQL_ROOT_PASSWORD: dotclear_root
MYSQL_DATABASE: dotclear_db
MYSQL_USER: dotclear_user
MYSQL_PASSWORD: dotclear_pwd
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
start_period: 10s
interval: 10s
timeout: 5s
retries: 3
# Doclear web application
dcstableapp:
image: jcpd/docker-dotclear:latest
container_name: dcstableapp
restart: unless-stopped
volumes:
- ./dcstable/app:/var/www/dotclear
depends_on:
dcstabledb:
condition: service_healthy
environment:
DC_DBDRIVER: mysqlimb4
DC_DBHOST: dcstabledb
DC_DBNAME: dotclear_db
DC_DBUSER: dotclear_user
DC_DBPASSWORD: dotclear_pwd
DC_DBPREFIX: dc_
DC_ADMINMAILFROM: contact@exemple.com
# Dotclear test
dcunstableapp:
image: jcpd/docker-dotclear:dev
container_name: dcunstableapp
restart: unless-stopped
volumes:
- ./dcunstable/app:/var/www/dotclear
depends_on:
npmapp:
condition: service_healthy
environment:
DC_DBDRIVER: sqlite
DC_DBNAME: \var\www\dotclear\sqlite.db
DC_ADMINMAILFROM: contact@exemple.com
On voit ici qu'on utilise l'image Docker de Doclear en version dev (de la branche unstable) et qu'on aura une base de données SQLite qui sera dans le même container. On enregistre en on relance la composition.
docker compose up -d
Comme le sous domaine par défaut de notre multiblog de test n'est pas blog
mais test
, il faut aussi modifier le fichier de configuration de Nginx :
nano dcunstable/app/servers/subdomain.conf
Et modifier :
# Redirect a particular subdomain
if ($dc_blog_id = 'blog') {
set $dc_blog_id default;
}
en remplaçant par :
# Redirect a particular subdomain
if ($dc_blog_id = 'test') {
set $dc_blog_id default;
}
On se rend dans le navigateur web à l'adresse du troisième blog https://test.mondomaine.tld
et on suit les étapes comme pour les deux premiers blogs.
Voilà, notre environnement multiblog Dotclear est prêt !
7. Plus loin
On va aller un peu plus loin en créant un petit script qui va mettre à jour notre environnement en une seul commande. Rien de bien méchant, il va juste mettre à jour les images des containers. (Et donc mettre à jour Dotclear également).
Dans le terminal SSH, on édite le fichier update.sh
:
nano update.sh
Dedans on va arrêter les containers, mettre à jour les images et redémarrer les container, ce qui donne :
#!/bin/sh -x
docker compose -p npmapp stop \
&& docker compose -p dcstabledb stop \
&& docker compose -p dcstableapp stop \
&& docker compose -p dcunstableapp stop \
&& docker pull jc21/nginx-proxy-manager:latest \
&& docker pull mariadb:latest \
&& docker pull jcpd/docker-dotclear:latest \
&& docker pull jcpd/docker-dotclear:unstable\
&& docker compose -f docker-compose.yml up -d \
&& docker image prune -af
On enregistre et on rend le fichier exécutable :
sudo chmod +x update.sh
On test :
update.sh
On doit voir les containers s'arrêter, les images se mettre à jour, et les containers redémarrer.
L'utilisation d'un proxy amène un autre problème, les IPs des utilisateurs ne sont pas transmises à Dotclear, ce qui va empêcher l'antispam de fonctionner correctement. On va corriger cela en ajoutant une règle dans notre configuration Nginx.
D'abord on va chercher l'IP interne de NPM, dans le terminal SSH on lance la commande :
docker network inspect npm
S'affiche alors un liste de configuration réseau des containers. On repère les lignes IPv4Address
, par exemple 172.20.0.2/16
, cela va nous servir de base.
On édite le fichier de configuration Nginx :
nano dcstable/app/servers/subdomain.conf
On ajoute juste après servers {
la règle suivant :
real_ip_header X-Forwarded-For;
set_real_ip_from 172.20.00./16;
On a pris une des IP listée ci-dessus et qu'on a simplifié en mettant 0 dans la place du dernier chiffre. Pour faire simple, on va transférer l'IP entrante pour tout ce qui vient du bloc d'IP 172.20.x.x. Une fois enregistré, on relance le container pour que ce soit pris en compte.
docker -p dcstableapp restart
L'antispam Dotclear nous dira merci.
8. FIN
Cette article est terminé. Il est loin d'être complet et à adapter à vos besoins mais c'est un bonne base pour savoir utiliser les images Docker de Dotclear.
La discussion continue ailleurs
URL de rétrolien : https://docker.dotclear.watch/trackback/249