Tutoriel: créer un environnement de développement de plugin Peertube rapidement en utilisant Docker (et qui permet de tester la fédération !)

Hello,

Je vais ici expliquer comment on peut facilement monter un environnement de développement de plugin Peertube, en local sur sa machine, en utilisant l’image Docker officielle.
Et cerise sur le gâteau: on va pouvoir faire tourner 2 instances, et tester les fonctionnalités de fédération !

Note: le présent tutoriel est un premier jet, il y a des choses qui peuvent être améliorées. Il contient également des petites bidouilles pour faire marcher le truc. Ça mériterais de corriger/modifier 2 ou 3 trucs pour être plus propre.

Le présent tutoriel est également un moyen simple pour vous de tester Peertube (et la fédération) localement sur votre machine !

Si quelqu’un⋅e souhaite le traduire en anglais (ou dans d’autres langues), pas de soucis. Tutoriel sous licence CC BY-NC-SA 4.0.

Objectifs

Faire docker-compose up, et avoir 2 instances Peertube qui se lancent, accessibles sur http://p1.localhost:9001/ et http://p2.localhost:9002/.
Ces deux instances peuvent se suivre si on le souhaite (et on pourra donc tester la fédération).

On veut également un mécanisme pour pouvoir tester un ou plusieurs plugins à partir de leurs sources (sans passer par le téléchargement depuis NPM). Utile pendant les phases de développement des plugins.

On pourra également débugguer le code des plugins directement depuis son IDE !! (Codium par exemple).

Pré-requis

Avoir Docker installé sur sa machine (pour la version, voir celle requise par Peertube).
On passera par docker-compose, qui est normalement inclus dans toutes les installations récentes de Docker.
Pour en savoir plus, voir la documentation Peertube.

Connaître un peu les concepts de base de Docker est également préférable.

TL;DR (Too Long, Don’t Read)

@mose propose ce dépôt dont le code est inspiré du présent tutoriel: https://codeberg.org/mose/pt-plugin-dev

Difficultés

Ce setup contourne quelques difficultés.

Par exemple, l’image Docker de Peertube est normalement faite pour tourner sur un environnement de production, pas de développement.

Si on veut que la fédération fonctionne sur du http (et non https), il faut notamment passer NODE_ENV à dev, ce que l’image Docker officielle ne sait pas gérer. Il faudra bidouiller pour lui fournir un fichier de conf spécifique: l’image prévoit un fichier production.yaml, mais quand NODE_ENV=dev, elle cherche à lire dev.yml. Résultat: certains chemins ne sont pas corrects.

Autre difficulté: avec l’un de mes plugin, j’ai rencontré des difficultés sur le front-end. J’ai du code qui utilise la lib crypto, qui n’est accessible que sur un contexte «sécurisé». Il faut être soit en https, soit sur localhost. À la base, je voulais faire un setup où les instances seraient accessibles sur une autre IP que localhost. Mais cela ne fonctionne pas dans mon cas.

Création de l’environnement

Préparation du dossier

On commence par créer un dossier vide quelque part. Ce dossier pourra par exemple s’appeler docker, mais son nom n’a pas d’importance.
Pour tout le reste des manipulations, il faudra se placer dans ce dossier.

Ensuite, on créé un sous-dossier docker-volume:

cd ~/votre_dossier_de_travail
mkdir docker-volume

Ce dossier contiendra toutes les données de vos instances Peertube.
Si vous voulez les ré-initialiser, vous pourrez supprimer tout son contenu, il sera recréé automatiquement (et vous aurez alors 2 instances vierges).

Fichiers d’environnement

On va maintenant créer 2 fichiers de variables d’environnements (un pour chaque instance), qui contiendra le nécessaire pour que les différentes images docker s’initialisent correctement.

Fichier .env1:

COMPOSE_PROJECT_NAME=peertube_federated

NODE_ENV=dev

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=peertube_dev
PEERTUBE_DB_USERNAME=postgres
PEERTUBE_DB_PASSWORD=postgres
PEERTUBE_DB_SSL=false
PEERTUBE_DB_SUFFIX=_dev
PEERTUBE_DB_HOSTNAME=postgres1
PEERTUBE_REDIS_HOSTNAME=redis1

PEERTUBE_WEBSERVER_HOSTNAME=p1.localhost
PEERTUBE_WEBSERVER_PORT=9001
PEERTUBE_WEBSERVER_HTTPS=false
PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback"]

PEERTUBE_SECRET=e4968005ab5a018972cbc386c91375cc8691678a16fc0c0e23de87a0781930ce
# vous pouvez préciser un mail pour le user root qui sera créé:
PEERTUBE_ADMIN_EMAIL=john@example.com

Fichier .env2:

COMPOSE_PROJECT_NAME=peertube_federated

NODE_ENV=dev

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=peertube_dev
PEERTUBE_DB_USERNAME=postgres
PEERTUBE_DB_PASSWORD=postgres
PEERTUBE_DB_SSL=false
PEERTUBE_DB_SUFFIX=_dev
PEERTUBE_DB_HOSTNAME=postgres2
PEERTUBE_REDIS_HOSTNAME=redis2

PEERTUBE_WEBSERVER_HOSTNAME=p2.localhost
PEERTUBE_WEBSERVER_PORT=9002
PEERTUBE_WEBSERVER_HTTPS=false
PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback"]

PEERTUBE_SECRET=eda7f9d5851a322fe9f9d0e5a72fdb49e6e9d637c766dee2c22eab24c34c0610
PEERTUBE_ADMIN_EMAIL=john@example.com

Note: ces fichiers contiennent des clés secrètes qui doivent normalement être générées aléatoirement. On est ici sur ne création d’environnement de test, qui ne sera pas accessible depuis l’extérieur de votre machine. Vous pouvez reprendre les clés d’exemple, ou en générer vous même avec la commande openssl rand -hex 32.

Fichier dev.yaml

Comme expliqué plus haut, le fait de placer NODE_ENV=dev pose des problèmes pour l’utilisation de l’image Docker de Peertube. On va bidouiller pour passer outre.

Pour cela, on va créer à la racine du dossier de travail les 2 fichiers suivants:

Fichier dev1.yaml:

listen:
  port: 9001

storage:
  tmp: '../data/tmp/'
  bin: '../data/bin/'
  avatars: '../data/avatars/'
  videos: '../data/videos/'
  streaming_playlists: '../data/streaming-playlists'
  redundancy: '../data/redundancy/'
  logs: '../data/logs/'
  previews: '../data/previews/'
  thumbnails: '../data/thumbnails/'
  torrents: '../data/torrents/'
  captions: '../data/captions/'
  cache: '../data/cache/'
  plugins: '../data/plugins/'
  client_overrides: '../data/client-overrides/'

Fichier dev2.yaml:

listen:
  port: 9002

storage:
  tmp: '../data/tmp/'
  bin: '../data/bin/'
  avatars: '../data/avatars/'
  videos: '../data/videos/'
  streaming_playlists: '../data/streaming-playlists'
  redundancy: '../data/redundancy/'
  logs: '../data/logs/'
  previews: '../data/previews/'
  thumbnails: '../data/thumbnails/'
  torrents: '../data/torrents/'
  captions: '../data/captions/'
  cache: '../data/cache/'
  plugins: '../data/plugins/'
  client_overrides: '../data/client-overrides/'

Fichier docker-compose.yml

On peut maintenant créer le fichier docker-compose.yml suivant:

version: "3.3"

services:

  p1.localhost:
    image: chocobozzz/peertube:production-bullseye
    # Vous pouvez également prendre une version précise de Peertube:
    # image: chocobozzz/peertube:v5.0.0-bullseye

    env_file:
      - .env1
    ports:
     - "127.0.0.1:9001:9001"
     - "127.0.0.1:9229:9229"
     - "127.0.0.1:1935:1935"
    command:
      - node
      - "--inspect=0.0.0.0"
      - "dist/server"
    volumes:
      - ./docker-volume/data1:/data
      - ./docker-volume/config1:/config
      - ./dev1.yaml:/config/dev.yml:ro
      # Ci-dessous, ajoutez les chemins vers les sources des plugins que vous voulez pouvoir tester:
      # - ../peertube-plugin-livechat/:/peertube-plugin-livechat:ro
    depends_on:
      - postgres1
      - redis1

  postgres1:
    image: postgres:13-alpine
    env_file:
      - .env1
    volumes:
      - ./docker-volume/db1:/var/lib/postgresql/data

  redis1:
    image: redis:6-alpine
    env_file:
      - .env1
    volumes:
      - ./docker-volume/redis1:/data

  p2.localhost:
    image: chocobozzz/peertube:production-bullseye
    env_file:
      - .env2
    ports:
     - "127.0.0.1:9002:9002"
    volumes:
      - ./docker-volume/data2:/data
      - ./docker-volume/config2:/config
      - ./dev2.yaml:/config/dev.yml:ro
      # - ../peertube-plugin-livechat/:/peertube-plugin-livechat:ro
    depends_on:
      - postgres2
      - redis2

  postgres2:
    image: postgres:13-alpine
    env_file:
      - .env2
    volumes:
      - ./docker-volume/db2:/var/lib/postgresql/data

  redis2:
    image: redis:6-alpine
    env_file:
      - .env2
    volumes:
      - ./docker-volume/redis2:/data

Quelques remarques sur ce fichier

Vous pouvez utiliser l’image de Peertube que vous voulez. Y compris une image que vous avez construite localement (si vous voulez par ex tester des développements sur Peertube).

Sur l’instance p1.localhost, on va également ouvrir le port 1935 pour pouvoir y diffuser du live.
On va également y ouvrir le port 9229 pour le debugger. Et on modifiera sa commande de démarrage, pour activer le débogguage (cf l’entrée command).
L’instance p2.localhost n’aura pas ces fonctionnalités (mais libre à vous de les activer, en pensant à changer les ports côté hôte).

Les fichiers dev1.yml et dev2.yml sont montés en lecture seule dans l’image. Cf plus haut.

Il faudra également monter (en lecture seule de préférence) les plugins sur lesquels vous voulez pouvoir travailler. Ajoutez un volume par plugin, en adaptant les chemins côté hôte pour pointer vers vos dossiers de travail.
À noter que ceci ne fait que rendre accessible le code de vous plugin dans les images Docker, cela n’installe pas les plugins (voir plus loin).

Pour que les 2 Peertube arrivent à communiquer, il faut que les noms des conteneurs correspondent au domaine utilisé: si on y accède par http://p1.localhost:9001, il faut que le conteneur s’appelle p1.localhost.

Lancer les images

Il est maintenant temps pour vous de vérifier que tout ça démarre correctement !

docker-compose up

Et pour les couper, utilisez CTRL+c.

Vous pouvez y accéder dans vos navigateurs web via http://p1.localhost:9001 et http://p2.localhost:9002.

Les comptes utilisateur⋅rice créés ont pour identifiant root et mot de passe test.

Vous pouvez faire en sorte que l’instance p1 suive p2 en allant sur http://p1.localhost:9001/admin/follows/following-list, puis en cliquant sur «suivre» et en entrant p2.localhost:9002.
Et vous pouvez reproduire la manipulation dans l’autre sens si besoin.

Astuce: accéder à l’intérieur d’un conteneur

Si vous avez besoin d’accéder au Bash de l’un des conteneur pendant qu’il tourne :

docker exec -it docker_federated_p1.localhost_1 bash

Installer un plugin local

Bon, maintenant qu’on a des Peertubes qui tournent, comment y installer ou mettre à jour un plugin localement ?

Si vous avez bien suivi les instructions, le code source de votre plugin devrait être monté dans les images docker sur un chemin du type /peertube-plugin-livechat (je prend ici en exemple le plugin livechat, mais bien sûr il faut adapter).
Il faut maintenant demander à Peertube de l’installer.

Note: Cette partie du tutoriel est améliorable. J’ai sur ma machine le peertube CLI. Si vous ne l’avez pas déjà, il y a d’autres méthodes qui seraient peut être plus directes (par exemple en lançant un Bash dans le conteneur, puis en utilisant les commandes NPM documentées). Mais je ne veux pas documenter quelque chose que je n’ai pas testé ^^.

Pour installer rapidement un CLI Peertube sur votre machine, vous pouvez suivre cette documentation (dans un autre dossier !!): CLI tools guide | PeerTube documentation

On pourrait également imaginer le compiler dans les images dockers (il suffirait de faire un npm run setup:cli).

Pour la suite, je vais supposer que vous avez un CLI Peertube sur la machine hôte.

Pour installer le plugin sur l’hôte p1:

cd ~/le_chemin_vers_votre_CLI/
node peertube.js plugins install --path '/peertube-plugin-livechat' --url "http://p1.localhost:9001" --username root --password 'test'

Pour désinstaller un plugin:

cd ~/le_chemin_vers_votre_CLI/
node peertube.js plugins uninstall --npm-name 'peertube-plugin-livechat' --url "http://p1.localhost:9001" --username root --password 'test'

Vous devrez le réinstaller à chaque modification de votre code source.

Note : à chaque installation de plugin, il y a un dossier de cache /home/peertube/.cache/yarn qui grossi. On peut vite fait atteindre plusieurs Go de données inutiles.
Je me suis fait un script maison qui fait les installations de plugin, et j’y ai ajouté après chaque installation la commande suivante (à faire depuis le dossier où vous avez configuré votre docker-compose, et pendant que les images sont actives) :

docker-compose exec -u peertube p1.localhost rm -rf /home/peertube/.cache/yarn

Débugguage

L’instance p1 démarre avec le mode de débugguage activé. Vous pouvez donc utiliser vos outils de debug pour tester vos plugins ! (ou même debug Peertube lui-même).

Par exemple, si vous utilisez Codium (ou Visual Studio Code), il vous suffit de créer un fichier .vscode/launch.json dans votre dossier de plugin:

{
  "configurations": [
    {
      "type": "node",
      "name": "p1.localhost",
      "request": "attach",
      "address": "p1.localhost",
      "port": 9229,
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/data/plugins/node_modules/peertube-plugin-livechat/"
    }
  ]
}

Placez vos points d’arrêt, et utilisez le menu «Debug > Start Debugging», et voilà !

Si vous voulez debug p2, adaptez le docker-compose.yml, et votre configuration launch.json.

3 « J'aime »

Note: il est possible de simplifier le process, notamment en utilisant des surcharges de fichiers d’environnement. Je modifierais prochainement ce tuto avec une méthode plus simple.

Voici une mise a jour de ce magnifique tutoriel sous forme de depot de source directement utilisable. Note, nous y avons travaillé ensemble avec @JohnLivingston ca ne vient pas de nulle part :wink:

2 « J'aime »

Merci, :slightly_smiling_face: :+1:
j’ai installe les instances et me suis logué sans soucis, ça tourne super bien.
Il me reste plus qu’a les faire parler ensemble et configurer codium.
Je vous ai envoyé une proposition de traduction en espagnol si cela vous conviens.
Bonne continuation.

1 « J'aime »