Migration depuis Mastodon vers GoToSocial auto-hébergé (en split-domain)
Cette semaine j'ai installé ma propre instance GoToSocial pour avoir le contrôle total sur ma présence sur le Fediverse.
J'ai rejoint le Fediverse il y a huit ans, le 5 avril 2017. C'était sur octodon.social
, une instance Mastodon lancée deux jours auparavant par cette personne fascinante qu'est Alice. Je ne savais pas trop à quoi m'attendre et j'y ai trouvé une espèce de revival du Twitter d'avant les influenceurs, par et pour toutes sortes de nerds et de weirdos, et sans trop voir le temps passer un jour est arrivée la mauvaise nouvelle : au jour de ses huit ans octodon.social
allait fermer ses portes définitivement.
Il me fallait donc déménager vers une autre instance, et tant qu'à faire pourquoi pas ne pas héberger moi-même quelque chose qui soit mon coin perso du Fediverse et qui ne se dérobera pas sous mes pieds ? J'ai donc opté pour GoToSocial et voici comment j'ai procédé pour le mettre en place :
Préparation
C'est une instance pour moi uniquement, donc le domaine jkbockstael.be
est tout indiqué. Le protocole ActivityPub permet le "split-domain", où le domaine d'un compte est différent du domaine sur lequel tourne le serveur qui gère ce compte. Concrètement ça me permet d'avoir le compte jkb@jkbockstael.be
alors qu'il y a déjà un site Web à la racine du domaine jkbockstael.be
. Le serveur utilisera le sous-domaine gotosocial.jkbockstael.be
qui est un CNAME
vers jkbockstael.be
puisqu'il n'y a pas de raison de le faire tourner ailleurs que mes autres machins Web.
Parenthèse serveur au passage pour se faire une idée de ce dont on dispose comme muscle : c'est un serveur virtuel que j'ai gonflé pour l'occasion afin d'avoir 1 CPU, 2 Go de RAM, et 50 Go d'espace disque. Pas exactement un monstre, moins cher qu'un menu au McDo, héberge déjà tout le reste.
ActivityPub se fait en HTTPS, et il y a déjà un certificat SSL wildcard pour *.jkbockstael.be
via Let's Encrypt. Rien à faire de ce côté-là. Comme GoToSocial tournera sur un serveur où Apache écoute déjà sur les ports 80 (HTTP) et 443 (HTTPS), il sera accessible au-travers d'un proxy. C'est ce proxy qui se chargera de la couche SSL.
Sur Octodon on va dans "Preferences" puis "Import and export" pour y obtenir son archive. Ce qui nous intéresse surtout c'est :
- Les comptes suivis, les comptes bloqués, et les bookmarks de posts
- L'archive de tous les posts publics ou non, et des médias qui vont avec
Les comptes qui me suivent seront pris en charge par le mécanisme de migration, je n'ai pas à m'en soucier.
Installation de GoToSocial
L'installation se fera dans /var/www/gotosocial.jkbockstael.be
.
GoToSocial est distribué en binaire exécutable, ça simplifie pas mal le processus d'installation :
sudo mkdir -p /var/www/gotosocial.jkbockstael.be
cd /var/www/gotosocial.jkbockstael.be/
sudo wget https://github.com/superseriousbusiness/gotosocial/releases/download/v0.18.3/gotosocial_0.18.3_linux_amd64.tar.gz
sudo tar -xzf gotosocial_0.18.3_linux_amd64.tar.gz
sudo rm gotosocial_0.18.3_linux_amd64.tar.gz
On va utiliser le disque du serveur comme espace pour le cache et les médias locaux, donc on crée un répertoire sur place :
sudo mkdir storage
On peut maintenant passer à la configuration.
Configuration
Un fichier de configuration complet est fourni comme base de travail, on le copie et l'édite :
sudo cp example/config.yaml config.yaml
sudoedit config.yaml
Seules quelques valeurs dévient de la configuration par défaut :
host: "gotosocial.jkbockstael.be"
# On est derrière un proxy, qui tourne sur la même machine
bind-address: "localhost"
port: 8080
# SQLite comme base de données, dans le répertoire courant
db-type: "sqlite"
db-address: "sqlite.db"
# Le répertoire de médias et cache créé précédemment
storage-local-base-path: "/var/www/gotosocial.jkbockstael.be/storage"
# C'est le proxy qui se charge du SSL, pas GoToSocial
letsencrypt-enabled: false
Il y a une palanquée de paramètres en plus de ceux-ci. Leur ajustement se fera (ou pas) sur la durée, quand l'usage prolongé aura clarifié les idées autour de ce qui devrait changer ou pas.
Les paramètres d'invalidation du cache des médias, par exemple, dépendent des contraintes d'espace mais surtout du rythme auquel ces médias s'accumulent donc du volume d'activité fédérée. Difficile de deviner d'avance quel serait le "sweet spot" donc on n'y touche pas dans l'immédiat.
Reverse proxy
GoToSocial peut prendre en charge les requêtes HTTP, mais sur ce serveur il y a déjà Apache qui prend les ports 80 et 443 pour d'autres services (site web, blog, FreshRSS, WebDAV) donc on va le configurer en reverse proxy pour le sous-domaine gotosocial.jkbockstael.be
.
Avant tout, s'assurer que tous les modules Apache requis sont bien actifs. En particulier on va avoir besoin de pouvoir prendre des requêtes WebSocket puisque certains clients ouvrent un WebSocket pour rafraîchir le flux en direct.
sudo a2enmod proxy_http ssl headers rewrite proxy proxy_http proxy_wstunnel
sudo systemctl restart apache2
On peut à présent créer et éditer une nouvelle config VHost pour Apache :
sudoedit /etc/apache2/sites-available/gotosocial.jkbockstael.be.conf
Dans cette configuration :
- tout se passe en HTTPS
- c'est le proxy qui prend en charge le SSL
- tout part vers GoToSocial qui écoute en HTTP sur le port
8080
- les connexions WebSocket sont prises en charge
<VirtualHost *:80 >
ServerName gotosocial.jkbockstael.be
</VirtualHost>
<VirtualHost *:443>
ServerName gotosocial.jkbockstael.be
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/jkbockstael.be/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/jkbockstael.be/privkey.pem
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/ upgrade=websocket
ProxyPassReverse / http://127.0.0.1:8080/
RequestHeader set "X-Forwarded-Proto" expr=https
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule "^/ws/(.*)" "wss://127.0.0.1:8080/ws/$1" [P,L]
CustomLog /var/log/apache2/gotosocial.jkbockstael.be_access.log combined
ErrorLog /var/log/apache2/gotosocial.jkbockstael.be_error.log
</VirtualHost>
Reste à l'activer :
sudo a2ensite gotosocial.jkbockstael.be.conf
sudo systemctl reload apache2
Split-domain
Je pourrais très bien me contenter de ça et utiliser le sous-domaine gotosocial.jkbockstael.be
, mais le protocole ActivityPub permet le "split-domain", c'est-à-dire de présenter au monde un domaine différent de celui sur lequel le serveur tourne. Concrètement ça se fait en distinguant dans les messages le host domain
où joindre le serveur du account domain
à indiquer après le nom de l'utilisateur.
Dans mon cas je veux que mon account domain
soit jkbockstael.be
tout court afin que mon identifiant sur le Fediverse soit identique à mon adresse e-mail : jkb@jkbockstael.be
. Je trouve ça cool, et puis c'est plus court que jkb@gotosocial.jkbockstael.be
.
Donc on édite la config de GoToSocial :
sudoedit config.yaml
Et on y change un seul paramètre :
account-domain: "jkbockstael.be"
Les autres instances vont utiliser le protocole WebFinger pour obtenir des informations sur mon compte, il faut donc que sur le domaine jkbockstael.be
on soit prêt à les traiter. Ça va passer par des redirections qu'on va définir dans le VHost correspondant :
sudoedit /etc/apache2/sites-available/www.jkbockstael.be.conf
On ajoute trois directives RewriteRule
qui transmettent les paramètres de requêtes :
RewriteEngine On
RewriteRule "\.well-known/webfinger" "https://gotosocial.jkbockstael.be/.well-known/webfinger" [R=301,L,QSA]
RewriteRule "\.well-known/host-meta" "https://gotosocial.jkbockstael.be/.well-known/host-meta" [R=301,L,QSA]
RewriteRule "\.well-known/nodeinfo" "https://gotosocial.jkbockstael.be/.well-known/nodeinfo" [R=301,L,QSA]
Et on rafraîchit Apache pour les prendre en compte :
sudo systemctl reload apache2
Service systemd
Maintenant qu'on a configuré le serveur et le reverse proxy il reste à ajouter une définition de service pour que systemd
le lance automatiquement au démarrage. Ça commence par la création d'un utilisateur système dédié, comme il se doit :
sudo useradd --system gotosocial
Ça va en même temps lui créer un groupe dédié. On peut maintenant réaffecter la propriété de tous le répertoire de travail du serveur GoToSocial :
sudo chown -R gotosocial:gotosocial /var/www/gotosocial.jkbockstael.be
On a une base de travail pour le fichier de définition de service dans les exemples fournis par GoToSocial :
sudo cp example/gotosocial.service /etc/systemd/system/
sudoedit /etc/systemd/system/gotosocial.service
Seules deux directives y sont à changer :
ExecStart=/var/www/gotosocial.jkbockstael.be/gotosocial --config-path config.yaml server start
WorkingDirectory=/var/www/gotosocial.jkbockstael.be
Activation du service
On peut maintenant activer ce service, ce qui va dans les faits démarrer immédiatement le serveur GoToSocial :
sudo systemctl enable --now gotosocial.service
Et voilà j'ai ma propre instance sur le Fediverse !
Création du compte administrateur
Bon par contre une instance sans personne dessus ça ne rime à rien, donc on va créer un compte utilisateur et le promouvoir comme administrateur, au moyen de l'interface ligne de commande de GoToSocial :
sudo -u gotosocial ./gotosocial --config-path config.yaml admin account create --username jkb --email jkb@jkbockstael.be --password 'SuperMotDePasse'
sudo -u gotosocial ./gotosocial --config-path config.yaml admin account promote --username jkb
Ceci conclut les opérations en ligne de commande sur le serveur. Le reste va se dérouler dans un navigateur Web ou sur un poste de travail.
Profil de l'utilisateur
On peut maintenant s'identifier avec ce compte fraichement créé en navigant à https://gotosocial.jkbockstael.be/settings
, où on a accès aux paramètres du compte utilisateur ainsi qu'aux paramètres de l'instance (puisque c'est un administrateur).
On en profite pour passer dans Administration > Instance
pour donner un nom et une description à l'instance, qui apparaîtront à l'adresse https://gotosocial.jkbockstael.be
.
Blocklists
Dans cette interface de configuration, sous Moderation > Domain Permissions
se trouvent les outils pour bloquer certains domaines avec lesquels ne pas fédérer. J'y ai importé des listes provenant de Seirdy et Garden Fence, ainsi que le fichier blocked_domains.csv
précédemment exporté depuis Octodon.
De cette manière je n'ai pas à me soucier de la partie putride du Fediverse, dont vous pouvez très bien totalement ignorer l'existence si les admins des instances par lesquelles vous êtes passé ont bien fait leur boulot.
On peut à présent effectuer la migration.
Migration depuis Octodon
Une migration de compte se fait en deux temps :
- indiquer sur l'instance de destination que le compte qui s'y trouve est un alias du compte qu'on va y migrer
- initier la migration depuis l'instance de départ
Sur l'instance de départ le compte va être indiqué comme migré, et les visiteurs du profil y verront un lien clair menant vers l'instance de destination. Tous les followers seront automatiquement abonnés au compte de l'instance de destination.
Donc premièrement dans GoToSocial, toujours dans l'interface de configuration, on va dans User > Migration
et on y ajoute https://octodon.social/@jkb
comme alias, sans oublier d'enregistrer ce changement.
Ensuite sur Octodon (qui tourne sous Glitch-Soc et a donc l'interface utilisateur de Mastodon), on va dans Preferences > Account > Move to a different account
y indiquer qu'on migre vers jkb@jkbockstael.be
et on lance le processus.
Ce processus de migration n'importe que les followers. Le contenu posté, les bookmarks, les comptes suivis (follows), et les comptes bloqués ne sont pas importés.
Pour les follows et les bloqués on peut importer directement les fichiers CSV qu'on avait exportés auparavant, en allant dans User > Export & Import > Import Data
.
Importation des posts
Parmi les données exportées depuis l'instance Octodon se trouve l'archive de toute l'activité du compte. Sur un poste de travail et au moyen de l'outil en ligne de commande slurp on peut l'importer dans le compte nouvellement crée, en tout cas les posts publics qui ne sont pas des réponses et ne mentionnent aucun compte qui n'existerait plus. Ces posts importés seront datés avec la date et heure d'origine, et publiés de manière à ne provoquer aucune notification chez les followers.
L'outil slurp
est en Go et distribué en source, il faut installer Go dans sa version la plus récente pour le compilers. Sur mon poste sous Ubuntu 22.04 ça passe par un PPA :
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt install golang
On peut à présent compiler slurp
:
git clone https://github.com/VyrCossont/slurp.git
cd slurp
go mod download
go build .
Une fois slurp
compilé, on va l'autoriser à poster sur notre nouveau compte :
./slurp --user jkb@jkbockstael.be auth login
Ça ouvre un formulaire d'identification dans un navigateur Web, et une fois identifié on reçoit un token à coller dans slurp
.
Maintenant que c'est fait on peut importer l'archive, qui a dans ce cas-ci été décompressée dans ../archive/
(vu du répertoire de slurp
) :
./slurp --user jkb@jkbockstael.be archive import \
--file ../archive \
--status-map-file ../archive/status-map.json \
--attachment-map-file ../archive/attachment-map.json \
--allow-missing-custom-emojis
Les fichiers status-map.json
et attachment-map.json
n'existent pas encore. Ce sont des fichiers que slurp
va remplir en important, ce qui lui permet de reprendre une importation interrompue. Toujours bon à savoir.
L'option --allow-missing-custom-emojis
indique d'importer les posts qui utilisent des emojis particuliers à l'instance de départ dont on ne disposerait pas sur l'instance d'arrivée. Ils seront remplacés dans le texte par leur nom entre deux points :comme_ceci:
.
Dans mon cas il a fallu vaguement une heure pour importer un peu plus de 2000 posts et tous leurs médias attachés.
Importation des bookmarks
Les bookmarks qu'on a exporté en CSV peuvent aussi être importés à l'aide de slurp
:
./slurp bookmarks import --user jkb@jkbockstael.be --file ../bookmarks.csv
Là aussi il faut un peu de patience, et ne pas s'étonner que slurp
soit silencieux pendant le processus.
Client Web
GoToSocial ne fournit pas de front-end Web. Certes il y a bien mon profil utilisateur à https://gotosocial.jkbockstael.be/@jkb
, mais rien pour consulter mon flux d'abonnements ou poster quoi que ce soit.
Pour ce faire j'utilise Pinafore qui est un front-end très léger et simple, qui a le mérite de tout enregistrer dans le navigateur. Ça fait le boulot mais c'est un tout petit peu trop simple sur un aspect : aucun moyen de choisir la langue dans laquelle on écrit. Oui c'est développé par un Américain, pourquoi ?
Client mobile
Sur Android j'utilise Tusky que je connais bien, y ajouter mon nouveau compte s'est passé sans problème.
Client TUI
Et puisqu'on n'est pas à une geekerie près, dans le terminal j'utilise Toot qui a un processus d'identification via token obtenu par un login dans navigateur Web comme pour slurp
auparavant :
sudo apt install pipx
pipx install toot
toot login
Une fois le token collé, on peut parcourir son flux avec toot
:
toot tui
Et voilà
Voilà qui conclut le processus de mon indépendance sur le Fediverse, j'espère que ces notes rassemblées seront utiles à quelqu'un un jour à qui ça épargnera pas mal de lecture de documentation.
Par la nature de la fédération le processus de migration est loin d'être instantané, mais j'ai retrouvé mes marques et mes têtes connues et je dois bien avouer être impressionné par la facilité du machin. On verra à l'usage quels réglages il faudra faire côté serveur, principalement en matière de cache. À un moment je prendrai peut-être aussi le temps d'éditer les CSS de la page de description de l'instance et de ma page de profil utilisateur pour qu'elles soient cohérentes avec le reste du domaine jkbockstael.be
, mais ce n'est pas au sommet de mes priorités.