Entretenir son instance Mastodon perso vite faite-mal faite

Cet article fait suite à celui-ci. Mais vous n'êtes pas obligés de lire ce dernier pour trouver des infos utiles ici.

Vous avez suivi mon guide

Et voilà que vous vous retrouvez avec une instance montée un peu à l’arrache, et que finalement vous avez pris goût à Mastodon. Mais vous n'êtes quand même pas prêt à vous lancer dans une migration de grande ampleur sur un serveur tout propre1. Pas de panique, moi non plus. Et comme j’ai appris quelques trucs utiles depuis la dernière fois, je me suis dit que j’allais vous en faire profiter.

L’entretien automatique régulier

Commençons par le plus important : j'étais passé rapidement sur les quelques tâches crons proposées par la documentation, parce qu’il s’agissait apparemment de tâches de maintenance superflues pour une petite instance (suppression de comptes non-validés ou de médias orphelins, etc…). Sauf que j’ai manqué une tâche plutôt importante : renouveler les abonnements PubSubHubbub régulièrement. En gros, si vous ne l’exécutez pas, vos abonnements vont finir par périmer et vous ne recevrez plus les nouveaux toots des personnes que vous suivez. Un peu gênant.

Heureusement, c’est facilement réparable. Et pour faire bonne mesures on va gérer toutes les tâches de maintenance, comme ça ce sera fait.

Commençons par créer un script shell contenant les commandes à lancer :

#> touch /root/mastodon-cron.sh
#> chmod u+x /root/mastodon-cron.sh
#> nano /root/mastodon-cron.sh

Comme d’habitude, vous pouvez utiliser l'éditeur de texte qui vous plaît le mieux, je ne suis pas éditiste2. Le fichier à écrire suit :

/root/mastodon-cron.sh
#!/bin/sh

cd /root/mastodon
docker-compose run --rm web rake mastodon:media:clear
docker-compose run --rm web rake mastodon:push:refresh
docker-compose run --rm web rake mastodon:push:clear
docker-compose run --rm web rake mastodon:feeds:clear

Donc : chaque ligne va exécuter une tache différente en utilisant rake qui est un machin Ruby. Et pour lancer cette commande, il faut se connecter à la machine web du service docker-compose mastodon. Facile3. La ligne la plus importante est celle du mastodon:push:refresh, qui, comme je le disais, permet de renouveler vos abonnements.

Il ne reste plus qu'à lancer ce script automatiquement et régulièrement. Pour cela on va utiliser le processus cron, qui sert précisemment à ça. Ce processus prend ses instructions de plusieurs sources, et notamment du fichier /etc/crontab. Rajoutez-y donc la ligne suivante :

/etc/crontab
[...]
25 1 * * * root cd /root && ./mastodon-cron.sh

Cette ligne demande à cron d’aller dans le répertoire /root et d’exécuter ./mastodon-cron.sh tous les jours à 01:25.

Back-up all the things

Maintenant qu’on tient à ses petits toots et ses followers, on se dit que ce serait sans doute une bonne idée de faire des sauvegardes de tout ça de temps en temps. Surtout que si vous avez eu la bonne idée de suivre mon guide précédent, ces données ne sont pas stockées simplement sur le disque mais dans un volume docker. Et les récupérer après un crash risque de ne pas être simple.

Mais quelles sont les données à sauvegarder dans Mastodon ? Il y en a plusieurs :

  • les données principales (toots, comptes, etc) sont stockées dans une base de données postgres (le conteneur docker db) ;

  • les images et autres médias attachés aux toots (stockées dans /root/mastodon/public/system/media_attachments ;

  • les données en cache avant d'être stockées en base passent par une base de données redis (conteneur docker redis).

Comme on reste dans le vite fait-mal fait, on ne va sauvegarder que les données vraiment essentielle, donc juste la base postgres. Pour ça, comme pour les tâches cron précédentes, on va lancer un dump de la base de données en s’attachant au conteneur db. Dis-comme ça ça à l’air compliqué, mais en réalité c’est l’affaire d’une ligne :

#> docker exec -t mastodon_db_1 pg_dumpall -c -U postgres > fichierdebackup.sql

Histoire de mettre ça un tout petit peu plus propre, on va en faire un script.

#> mkdir -p /root/mastodon-backups/postgres
#> touch /root/mastodon-backups/backup-postgres.sh
#> chmod u+x /root/mastodon-backups/backup-postgres.sh
#> nano /root/mastodon-backups/backup-postgres.sh
/root/mastodon-backups/backup-postgres.sh
#!/bin/sh

docker exec -t mastodon_db_1 pg_dumpall -c          \
                                        -U postgres \
 > /root/mastodon-backups/postgres/dump_$(date +%Y%m%d_%H%M%S).sql

À chaque fois que le script sera exécuté, il dumpera toute la base de donnée Mastodon dans un fichier sql dont le nom comportera la date et l’heure. Ça sera plus simple pour s’y retrouver. Libre ensuite à vous d’ajouter la tâche de backup à un cron, comme vu précédemment. Attention toutefois, le fichier pèse vite plusieurs dizaine de mégaoctets, et si vous avez fait comme moi vous n’avez toujours qu’un misérable SSD de 10Go…

Pensez également à rapatrier régulièrement les sauvegardes chez vous pour les stocker ailleurs que sur le serveur4. Le plus simple c’est encore de faire ça avec scp, la commande de copie par SSH. Après vous pouvez automatiser ça aussi, mais on sort un peu du cadre de cet article.

#> cp -r /root/mastodon-backups/postgres /tmp
#> chown -R ubuntu. /tmp/postgres
#> exit
$> exit
Connection to mastodon closed
$> scp -r mastodon:/tmp/postgres /tmp
dump_20170419_010711.sql                         100%   45MB 881.9KB/s   00:52
dump_20170423_145803.sql                         100%   59MB 699.0KB/s   01:27
dump_20170415_120807.sql                         100%   35MB 886.6KB/s   00:41
dump_20170417_001920.sql                         100%   37MB 782.1KB/s   00:49

Et la restauration dans tout ça ? Là encore c’est très simple5 : une fois votre conteneur db vide recréé et lancé, choisissez le fichier sql que vous voulez restaurer et utilisez simplement psql (à l’intérieur du conteneur, bien entendu).

#> cat dump_YYYYMMDD_HHMMSS.sql | docker exec -i mastodon_db_1 psql -U postgres

Mise-à-jour mon amour

J’en avais déjà parlé dans le guide précédent, mais le processus de mise-à-jour de Mastodon s’est (un peu) stabilisé. Au lieu d’utiliser la branche master en production certain commits sont désormais taggés avec un numéro de version et sont considérés comme stables. Pour mettre à jour il va donc vous falloir repérer le numéro de version le plus haut disponible, comme dans l’exemple suivant.

#> cd /root/mastodon
#> git fetch # On récupère les nouveaux commits
remote: Counting objects: 3034, done.
remote: Total 3034 (delta 1216), reused 1216 (delta 1216), pack-reused 1818
Réception d'objets: 100% (3034/3034), 1000.12 KiB | 747.00 KiB/s, fait.
Résolution des deltas: 100% (2069/2069), complété avec 457 objets locaux.
Depuis https://github.com/tootsuite/mastodon
   40fd1de..1244630  master     -> origin/master
 * [nouvelle branche] admin/report-processing-improvements -> origin/admin/report-processing-improvements
 * [nouvelle branche] feature-oembed -> origin/feature-oembed
 * [nouvelle branche] feature-private-federation -> origin/feature-private-federation
   1ebcdf8..847de71  skylight   -> origin/skylight
 * [nouvelle étiquette] v1.2       -> v1.2
 * [nouvelle étiquette] v1.2.1     -> v1.2.1
 * [nouvelle étiquette] v1.2.2     -> v1.2.2

#> git tag   # On vérifie les tags
v0.1.0
v0.1.1
v0.1.2
v0.6
v0.7
v0.8
v0.9
v0.9.9
v1.0
v1.1
v1.1.1
v1.1.2
v1.2
v1.2.1
v1.2.2

#> docker-compose stop  # On arrête Mastodon
Stopping mastodon_web_1 ... done
Stopping mastodon_sidekiq_1 ... done
Stopping mastodon_streaming_1 ... done
Stopping mastodon_db_1 ... done
Stopping mastodon_redis_1 ... done

#> git checkout v1.2.2  # On met à jour le code
Note: checking out 'v1.2.2'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD est maintenant sur 2e4afcc... Fix #2108 - Fix gif uploads (#2171)

#> docker-compose build
[On reconstruit les conteneurs docker]

#> docker-compose run --rm web rails assets:precompile
[On recompile les ressources statiques]

#> docker-compose run --rm web rails db:migrate
[On met à jour la base]

#> docker-compose up -d
[On relance Mastodon]

Bien sûr vous pouvez continuer à utiliser master en production plutôt que les versions stables, pour tester des nouvelles features, etc. Mais inutile de remplir un rapport de bug sur le github ou de râler sur la mailing list si quelque chose se passe mal dans ce cas.

Espace de stockage

Même pour une petite instance, la manie de Mastodon à mettre en cache tous les toots et medias reçus consomme de l’espace disque régulièrement.

Au bout d’un mois mon petit disque basique de 10Go commençait à se remplir dangereusement. Pour le soulager j’ai loué un disque supplémentaire de 50Go pour 5€. Le prix de mon instance est donc monté de manière conséquente, ce qui me gêne un peu. De plus le volume de données stockée ne descendant pas, cette solution est nécessairement temporaire. Au moins jusqu'à la mise en place d’un garbage-collector pour les anciens toots, voir le remplacement de certains medias en cache par un lien vers leur instance d’origine 6.

En attendant, commander un disque additionnel via votre espace personnel OVH est une solution rapide est simple7.

Le bouton en bas à droite

Une fois votre disque acheté, vous pouvez vérifier qu’il vous a bien été livré en vous connectant à votre serveur et en utilisant la commande lsblk.

#> lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
vda    253:0    0    10G  0 disk
`-vda1 253:1    0    10G  0 part /
vdb    253:16   0    50G  0 disk

Vous pouvez voir ici mon ancien disque vda, comportant une unique partition vda1 et mon nouveau disque de 50Go vdb. Si votre nouveau disque n’apparaît pas, c’est qu’il n’est pas encore livré, attendez un peu puis réessayez. De toutes façon vous finirez par recevoir un mail d’OVH avertissant que le disque est bien livré.

Maintenant que le disque est identifié, il va s’agir de le partitionner, puis de créer des systèmes de fichier sur chaque partition, et enfin de monter ces systèmes de fichier à un endroit utile. Dans l’esprit de ce guide, on ne va créer qu’une partition, formatée en ext4 (parce que c’est simple et stable), et on va la monter sur /var/lib/docker pour héberger nos conteneurs docker et leurs volumes.

#> fdisk /dev/vdb

Command (m for help):

fdisk est un utilitaire de partitionnement standard. La commande lance un prompt pour vous demander ce que vous souhaitez faire. Notez que toute modification demandée ne sera finalement effectuée qu’au moment de quitter, et seulement si vous utilisez la commande w.

Pour créer une partition qui fasse toute la taille du disque, rien de plus simple : utilisez la commande n et validez toutes les options par défaut (partition primaire, numéro 1, le début coïncide avec le début du disque et la fin avec la fin du disque). Cela fait, utilisez w pour créer votre nouvelle partition et quitter. Vous avez maintenant accès à un fichier /dev/vdb1 qui représente votre partition (vous pouvez aussi le vérifier en relançant lsblk).

Il va maintenant s’agir de créer un système de fichier sur cette partition, pour qu’elle puisse être utilisable.

#> mkfs.ext4 /dev/vdb1

Simple, efficace. Il y a évidemment plein d’options qu’on peut préciser pour mkfs, mais qui a le temps pour ça ?

Avant de poursuivre et de créer le point de montage, on va monter notre nouveau système de fichiers sur /mnt pour transférer les données docker déjà existantes. Pour cela, il va bien sûr falloir stopper notre instance, mais aussi le service docker qui tourne en tâche de fond.

#> mount /dev/vdb1 /mnt
#> cd /root/mastodon
#> docker-compose stop
#> service docker stop
#> mv /var/lib/docker/* /mnt/
#> umount /mnt

Alternativement, à la place du mv vous pouvez faire une copie cp et renommer l’ancien /var/lib/docker en /var/lib/docker.sav pour pouvoir revenir en arrière au cas où. On n’est jamais trop prudent.

On veut maintenant éditer le fichier fstab pour indiquer au système qu’il faut monter notre nouveau disque par défaut sur /var/lib/docker, histoire que le service docker retrouve ses petits lorsqu’on le relancera. Pour cela, on va chercher l’UUID de notre partition via la commande blkid

#> blkid
/dev/vda1: LABEL="cloudimg-rootfs" UUID="522da1aa-ec5c-4a1b-b571-94e8c7a9bf63" TYPE="ext4"
/dev/vdb1: UUID="eb83e3b2-47fb-402e-99ac-9922b030aeb1" TYPE="ext4"

On peut voir notre premier disque, auquel les gens de chez OVH on d’ailleurs associé un LABEL pour le désigner plus facilement8, ainsi que notre nouveau disque dont on note l’UUID. On peut maintenant éditer le fichier /etc/fstab pour lui rajouter une ligne

#> nano /etc/fstab
/etc/fstab
LABEL=cloudimg-rootfs  /   ext4  defaults  0 0
UUID="eb83e3b2-47fb-402e-99ac-9922b030aeb1" /var/lib/docker ext4 defaults,errors=remount-ro 0 1

La première ligne était déjà présente et demande de monter notre premier dique comme racine du système. La deuxième est celle que nous rajoutons (avec l’UUID noté plus haut).

Cela fait, on peut vérifier que tout se passe bien en demandant le montage des disque via la commande mount.

#> mount -a
#> ls /var/lib/docker

Vous pouvez enfin vérifier que votre disque est correctement monté et que les fichiers docker sont bien à leur place dans /var/lib/docker comme s’ils n’en étaient jamais partis. C’est le moment de relancer le service docker, puis notre instance.

#> service docker start
#> cd /root/mastodon
#> docker-compose start

Et tout est bien qui finit bien. N’hésitez pas à regarder l’occupation de vos disques via la commande df -h et à soupir de contentement devant la place désormais disponible.

Conclusion

Après ces quelques précisions vous devriez avoir une instance un tout petit peu plus propre que précédemment. Cool, non ?

Je réitère cependant mes avertissements : ce guide, ainsi que le précédent, ne sont à mon avis pas suffisants pour vous lancer dans l’hébergement d’une instance ouverte au public. Administrateur système est un vrai métier9, et je vous conseille de ne pas sous-estimer la difficulter de gérer l’hébergement et la modération d’un service ouvert au public.


Évidemment, pour des commentaires, des suggestions et des insultes, vous pouvez me contacter via mon compte mastodon.


  1. par exemple en suivant le guide d’Angristan que j'évoquais précédemment
  2. J’ai même de très bons amis qui utilisent emacs
  3. non
  4. parce qu’une sauvegarde au même endroit que ce qu’elle est censé sauvegarder n’a qu’un intérêt tout relatif…
  5. En théorie, parce que courageux comme je suis je n’ai évidemment pas testé
  6. Apparemment une nouvelle tâche rake permettrai de faire quelque chose comme ça, je n’ai pas encore regardé de très près
  7. Mais un peu chère : 5€/mois pour 50Go, autant dire du vol
  8. On aurait pu le faire aussi, mais ça aurait impliqué de fouiller les options de mkfs.ext4
  9. Et un métier ingrat, en plus

Written by Lertsenem in selfhosting on Mon 24 April 2017. Tags: technical, socialnetwork, mastodon, twitter, self-hosted, noob,