Installation de NodeBB avec Docker
Note aux lecteurs
Cet article est vieillissant et son contenu doit être révisé. Attention donc : les explications, commandes systèmes et autres informations peuvent dorénavant être incorrectes ou inexactes.
1 - Introduction
Pour répondre à un besoin d'organisation pendant un projet de mon école, j'ai mis en place un forum. J'ai découvert NodeBB, un forum développé en NodeJS
. Il est gratuit, pratique, très rapide et customisable.
J'ai tout de suite été séduit par son interface, ses différents skins et son système de plugin.
2 - L'image
Mais son installation et son utilisation avec docker
n'a pas été une partie de plaisir au début, découvrant l'utilisation de docker
. De plus, l'équipe de développeurs du forum n'avait pas mis en place d'image officielle sur le docker hub. Il semble qu'une personne de la communauté ait créé une image pseudo-officielle, mais celle-ci n'était pas du tout à jour lorsque j'ai eu besoin du forum.
Heureusement, un utilisateur (benlubar) dans mon cas a créé une image qu'il met régulièrement à jour.
L'installation est simple, mais la persistance des données m'a donné du fil à retorde (voir mon post précédent) !
Pour commencer, téléchargez l'image de NodeBB
et de sa base de données Redis
.
docker pull benlubar/nodebb
docker pull redis:alpine
J'ai choisi l'image Redis
basé sur Alpine Linux, car :
[...] selon la porte-parole de Docker, Alpine Linux, -est- plus léger, plus rapide et plus sûr [...]
Et les images basées sur Alpine sont très petites, ce qui économise la place prise sur le serveur !
3 - Les paramètres
Comme je l'expliquais dans l'article sur docker
, j'ai choisi l'utilisation de scripts pour lancer et mettre à jour mes services.
3.1 - Redis
Pour lancer Redis
avec une configuration persistante, j'utilise l'option volume
de docker
. Cela me permets d'être certain que la configuration et le mot de passe ne varie pas d'un lancement à l'autre, pour que le forum puisse toujours y avoir accès.
-v /path/to/redis/redis.conf:/usr/local/etc/redis/redis.conf
Le fichier redis.conf
est créé automatiquement au lancement du conteneur, puis vous pouvez l'éditer et le relancer pour prendre en compte vos paramètres.
Dans mon cas, voila un aperçu de ce que j'ai modifié (je vous mets les mêmes titres qui se trouvent dans le fichier):
##### SNAPSHOTTING #####
save 120 1 # Sauvegarde toutes les 2 minutes s'il y a au moins 1 modification
save 60 10 # Sauvegarde toutes les minutes s'il y a 10 modifications
save 60 10000 # Idem pour 10 000
##### SECURITY #####
requirepass <Votre mot de passe>
##### APPEND ONLY MODE #####
appendonly yes
appendfilename "appendonly.aof" # Par defaut
appendfsync always # Les explications sont dans le fichier même
# appendfsync everysec # Idem
# appendfsync no # Idem
Pour la sauvegarde en arrière plan, redis à besoin de vm.overcommit_memory = 1
, qui est un paramètre du fichier /etc/sysctl.conf
(à éditer en root). Dans mon cas, il était à 0 (un paramètre par défaut de Debian j'imagine).
Une fois les modifications faites, il faut redémarrer ou faire :
$ sysctl vm.overcommit_memory=1 # Commande
vm.overcommit_memory = 1 # Réponse
Lancez le conteneur. Une fois lancé, faites docker logs redis
(si le conteneur s'appelle redis). Si tout va bien, vous devriez avoir plus ou moins:
1:C 27 Mar 14:49:05.288 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf # Et pourtant il utilise bien mon fichier de configuration a priori !
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.0.7 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 1
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
1:M 27 Mar 14:49:05.289 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. # Je n'ai pas encore réussi à régler le warning, qui n'empêche pas le bon fonctionnement.
1:M 27 Mar 14:49:05.289 # Server started, Redis version 3.0.7
1:M 27 Mar 14:49:05.344 * DB loaded from disk: 0.055 seconds
1:M 27 Mar 14:49:05.344 * The server is now ready to accept connections on port 6379
1:M 27 Mar 14:54:06.022 * 100 changes in 300 seconds. Saving...
1:M 27 Mar 14:54:06.022 * Background saving started by pid 11
11:C 27 Mar 14:54:06.092 * DB saved on disk
11:C 27 Mar 14:54:06.092 * RDB: 0 MB of memory used by copy-on-write
1:M 27 Mar 14:54:06.122 * Background saving terminated with success
Concernant la sauvegarde persistante des données, il faut passer en paramètre le dossier dans lequel elles seront copiées.
-v /path/to/redis/data:/data
Enfin, la documentation de Redis
propose d'utiliser une solution radicale pour la sauvegarde, appelée appendonly
. C'est-à-dire que chaque action dans la base de données sera consignée dans un fichier. Celui-ci sera lu à chaque démarrage, permettant de reconstruire la base.
Étant parti sur une autre solution de persistance des données, je ne l'ai pas testée mais je vous met la commande qu'ils proposent :
docker run --detach --name redis --user 1000:50 --volume=path/to/data:/data --entrypoint redis-server redis --appendonly yes
Pour en finir avec Redis
, je vous donne la partie de mon script de lancement :
echo -e "\n\t Lancement de Redis (redis serveur alpine)\n"
docker run -d \
--name redis-nodebb \
--restart=always \
-v /path/to/data:/data \
-v /path/to/redis.conf:/usr/local/etc/redis/redis.conf \
--entrypoint redis-server redis:alpine
3.2 - NodeBB
Comme j'utilise tous mes services sur le même serveur, avec une seule adresse IP, j'utilise un reverse-proxy (toujours avec docker). Il se charge d'acheminer les requêtes web vers le bon service en utilisant des noms de domaines (ou sous domaines).
Cela me permet aussi de ne pas exposer les ports de mes services directement sur internet, mais seulement sur le localhost (auquel accède le reverse-proxy).
Concernant le fichier de configuration du forum, c'est presque identique à ce que l'on a fait pour Redis
.
--volume=/path/to/config.json:/usr/src/app/config.json
Et voila le contenu de config.json
:
{
"url": "https://forum.lmilcent.com", # URL d'accès au forum
"secret": "<Mot de passe REDIS>", # Mot de passe de Redis
"database": "redis",
"port": 4567, # Accessible en localhost seulement
"redis": {
"host": "redis",
"port": "6379", # Accessible en localhost seulement
"database": "0"
}
}
Ce fichier là est bien plus court !
On indique maintenant au conteneur NodeBB
qu'il doit se lier au conteneur Redis
. Cela lui permet l'accès presque en direct et donc sans passer par internet.
--link redis:redis # --link <nom du conteneur>:<nom du service>
Et pour le moment, voilà tous les dossiers qui sont sauvegardés (pour la persistance des photos téléchargées par exemple):
--volume=/path/to/uploads/files:/usr/src/app/public/uploads/files \
--volume=/path/to/uploads/profile:/usr/src/app/public/uploads/profile \
--volume=/path/to/datas:/data \
Reste à verifier si tous les dossiers importants sont sauvegardés, mais pour le moment je n'ai rien à signaler.
Note: On ne peut pas remplacer les deux premières commandes (j'ai essayé !) par --volume=/path/to/uploads:/usr/src/app/public/uploads
. J'ai l'impression que docker
ne gère pas bien la récursion dans les sous-dossiers, ou que c'est le forum qui n'apprécie pas.
Enfin, j'utilise trois commandes pour le reverse-proxy et son "compagnon" let's encrypt
:
--env 'VIRTUAL_HOST=forum.lmilcent.com' \ # Indique l'URL d'accès
--env 'LETSENCRYPT_HOST=forum.lmilcent.com' \ # Pour générer un certificat HTTPS
--env 'LETSENCRYPT_EMAIL=<email>@lmilcent.com' \ # Idem
La commande complète de lancement devient donc:
echo -e "\n\tLancement de NodeBB (benlubar)\n"
docker run -d \
--name forum \
--restart=always \
--link redis:redis \
--env 'VIRTUAL_HOST=forum.lmilcent.com' \
--env 'LETSENCRYPT_HOST=forum.lmilcent.com' \
--env 'LETSENCRYPT_EMAIL=<email>@lmilcent.com' \
--volume=/path/to/config.json:/usr/src/app/config.json \
--volume=/path/to/uploads/files:/usr/src/app/public/uploads/files \
--volume=/path/to/uploads/profile:/usr/src/app/public/uploads/profile \
--volume=/path/to/datas:/data \
benlubar/nodebb
3.3 - Plugins
J'ai remarqué qu'après une suppression des conteneurs (pour une mise à jour des images par exemple), les plugins ne restaient pas (mais leurs réglages oui).
J'ai une astuce, je les installe en ligne de commande au moment où je crée le conteneur.
J'ajoute à la fin des deux commandes précédentes:
echo -e "\n\tInstallation du plugin Q&A\n"
docker exec -ti forum npm install nodebb-plugin-question-and-answer
echo -e "\n\tInstallation du plugin 2factor\n"
docker exec -ti forum npm install nodebb-plugin-2factor
echo -e "\n\tInstallation du plugin Cards\n"
docker exec -ti forum npm install nodebb-plugin-cards
echo -e "\n\tInstallation du plugin Gravatar\n"
docker exec -ti forum npm install nodebb-plugin-gravatar
echo -e "\n\tInstallation du plugin GitHub SSO\n"
docker exec -ti forum npm install nodebb-plugin-sso-github
echo -e "\n\tInstallation du plugin Emoji\n"
docker exec -ti forum npm install nodebb-plugin-emoji-extended nodebb-plugin-emoji-one
echo -e "\n\tActivation du plugin Emoji One\n"
docker exec -ti forum ./nodebb activate nodebb-plugin-emoji-one
echo -e "\n\tInstallation du plugin Poll (questionnaire)\n"
docker exec -ti forum npm install nodebb-plugin-poll
echo -e "\n\tInstallation du plugin custom fields\n"
docker exec -ti forum npm install nodebb-plugin-ns-custom-fields
echo -e "\n\tInstallation du plugin mailjet\n"
docker exec -ti forum npm install nodebb-plugin-emailer-mailjet
echo -e "\n\tInstallation du plugin bbcode parser\n"
docker exec -ti forum npm install nodebb-plugin-mega-bbparser
echo -e "\n\tInstallation du plugin pour permettre la couleur dans les posts\n"
docker exec -ti forum npm install nodebb-plugin-mega-colors
echo -e "\n\tDésactivation du plugin spam-be-gone\n"
docker exec -ti forum ./nodebb reset -p nodebb-plugin-spam-be-gone
echo -e "\n\tTerminé !\n"
echo -e "\n\tRedémarrage de NodeBB\n"
docker restart forum
La commande docker exec -ti forum npm install nodebb-plugin-poll
est très pratique, elle permet d'exécuter une commande dans le conteneur et de voir la sortie dans la console courante.
docker exec -ti <Nom du conteneur ou ID> <commande>
4 - Conclusion
C'est le service avec lequel j'ai eu le plus de mal, surtout à cause des données non persistantes. Mais une fois une documentation écrite c'est du gâteau !
Une question, un problème, une faute ? Contactez-moi :