Créer Son Instance Peertube Avec Docker-compose

Ça fait pas mal de temps que je rêvais de lancer une instance PeerTube pour héberger des vidéos sur l’esprit critique qu’on peut voir sur Youtube, et qui pourtant sont en licence Creative Commons.

Sachant que la plateforme Youtube est loin d’être la plateforme parfaite selon moi (pistage, recommandations qui posent problème, censure abusive fréquente des ayants droit et parfois de trolls, …)

Maintenant, rentrons dans le vif du sujet : comment déployer une instance PeerTube sur son serveur ?

Avant propos

Par convention, j’utiliserai les notations suivantes pour signifier l’usage de la ligne de commande :

  • quand une commande commence par root>, il s’agit d’une commande à exécuter en tant que root
  • quand une commande commence par un user>, il s’agit d’une commande à exécuter en tant que user (ou l’utilisateur qu’on va créer plus bas pour faire les commandes classiques)
  • quand il est précisé @sauvegarde, la commande devra être exécutée sur la machine de sauvegarde
root> <MA COMMANDE AVEC L'UTILISATEUR ROOT>
user> <MA COMMANDE AVEC L'UTILISATEUR CLASSIQUE (NON-ROOT)>
root@sauvegarde> <MA COMMANDE À ÉXECUTER EN TANT QUE ROOT SUR LA MACHINE DE SAUVEGARDE>

Quel serveur prendre ?

D’après la FAQ de PeerTube, bien qu’il soit pas conseillé d’auto-héberger une instance PeerTube sur un Raspberry Pi derrière une ligne ADSL, un serveur n’a pas besoin d’énormément de ressource sauf si vous souhaitez utiliser la fonction de transcoding.

N’ayant pas la fibre chez moi, j’ai opté pour un serveur hébergé dédié à bas coût (on verra en fonction des besoins pour migrer vers un serveur plus puissant). Ne voulant pas faire de publicité encore moins sans avoir essayé, je tais mon choix :).

Néanmoins, je peux dire que j’ai choisi la distribution Linux Debian Stretch : ce choix ce justifie surtout par mon expérience avec cette distribution (je l’utilise au quotidien, au travail comme chez moi depuis de nombreuses années). Je me doute qu’une autre distribution fera très bien l’affaire :), mais les commandes qui suivent dans cet article seront spécifiques à cette distribution.

Choisir un nom de domaine

Si vous voulez faire partie du fediverse (fédération des instances de Peertube), il faut que vous preniez un nom de domaine. Les noms de domaines sont assez peu coûteux et valables à l’année, mais si vous souhaitez en disposer d’un gratuit, voici quelques-uns :

Comment faciliter le déploiement

Mon choix a été relativement simple : l’auteur et la communauté de PeerTube ont mis à disposition de quoi déployer la solution en production avec docker-compose.

Autre avantage : Docker-Compose facilite le déploiement mais aussi les backups des volumes (BDD, vidéos, etc).

Par ailleurs, docker-compose offre la possibilité d’isoler chacun des composants de l’application : le serveur web (NodeJS), la base de données (Postgres) et Redis.

Installations des pré-requis

Il vous faudra installer :

Pour lancer Docker, je recommande de le lancer sans passer par l’utilisateur root. Pour créer l’utilisateur qui s’en chargera, lancez la commande suivante :

root> sudo adduser user # remplacer user par ce qui vous plaît

Et pour le rajouter au groupe docker (et ainsi l’autoriser à lancer docker) :

root> sudo groupadd docker
root> sudo usermod -aG docker user # user est à remplacer

Récupérer le code source de Peertube

Maintenant nous devons récupérer le code source de PeerTube pour construire l’image Docker du serveur web et récupérer les fichiers dont nous allons nous inspirer pour construire les différents services :

Pour cette section, je m’inspire (avec quelques libertés) de la procédure mise à disposition sur le projet.

root> su - user # user à adapter
user> git clone https://github.com/chocobozzz/PeerTube $HOME/peertube
user> cd $HOME/peertube

Ensuite, créer une branche sur laquelle nous allons pouvoir tweeker des fichiers de configuration et récupérer les mises à jour au fur et à mesure :

user> git checkout -b myinstance origin/master

Personnaliser le fichier docker-compose.yml

Le fichier docker-compose.yml que nous allons éditer se trouve dans $HOME/peertube/support/docker/production/docker-compose.yml.

Rajouter un reverse-proxy

Le reverse-proxy permettra de récupérer les requêtes entrantes pour :

  • Sécuriser la connexion en HTTPS (avec letsencrypt dans notre cas) ;
  • Faire éventuellement de la répartition de charge entre nos instances (pour un besoin futur ?) ;

J’ai vu qu’il existait Traefik pour cela et je voulais voir ce qu’offrait cette solution (pour faire un peu de veille technologique).

Son utilisation semble simple et supporte de base letsencrypt !

Pour cela, il suffit d’éditer le fichier docker-compose.yml pour ajouter les lignes suivantes :


 services:

+  reverse-proxy:
+    image: traefik
+    command: --api --docker # Enables the web UI and tells Træfik to listen to docker
+    ports:
+      - "80:80"     # The HTTP port
+      - "443:443"   # The HTTPS port
+      - "8080:8080" # The Web UI (enabled by --api)
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
+      - ./support/docker/production/acme.json:/acme.json
+      - ./support/docker/production/traefik.toml:/traefik.toml
+    restart: "always"
+
   peertube:
     build:
       context: .

…

     labels:
       traefik.enable: "true"
       traefik.frontend.rule: "Host:${PEERTUBE_WEBSERVER_HOSTNAME}"
       traefik.port: "9000"
-    # If you don't want to use a reverse proxy (not suitable for production!)
-    # ports:
-      # - "80:9000"
+      traefik.frontend.redirect.entryPoint: https # Activate redirection from HTTP to HTTPS

Désactiver traefik pour postgres et redis en rajoutant la section suivante pour chacune :

+    labels:
+      traefik.enable: "false"

Et faire ces commandes pour créer le fichier acme.json qui va bien :

user> touch $HOME/peertube/support/docker/production/acme.json && chmod 600 $HOME/peertube/support/docker/production/acme.json

Et rajouter le fichier traefik.toml. Ce fichier doit contenir les entrypoints ainsi que la configuration pour activer Letsencrypt.

Voici ce à quoi pourra ressembler ce fichier (attention à bien adapter ce qui convient si vous le copiez) :

# Uncomment this line in order to enable debugging through logs
# debug = true
defaultEntryPoints = ["http", "https"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

# Enable ACME (Let's Encrypt): automatic SSL.
[acme]

# Email address used for registration.
#
# Required
#
email = "<MY EMAIL ADDRESS>"

# File or key used for certificates storage.
#
# Required
#
storage = "acme.json"
# or `storage = "traefik/acme/account"` if using KV store.

# Entrypoint to proxy acme apply certificates to.
# WARNING, if the TLS-SNI-01 challenge is used, it must point to an entrypoint on port 443
#
# Required
#
entryPoint = "https"

# Domains list.
#
[[acme.domains]]
  main = "<MY DOMAIN>"

# Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge
#
# Optional but recommend
#
[acme.httpChallenge]

  # EntryPoint to use for the challenges.
  #
  # Required
  #
  entryPoint = "http"

Modifier les variables d’environnement

Dans la section peertube: puis environment: se trouve plusieurs variables d’environnement. Ces variables d’environnement sont listées dans le fichier $HOME/peertube/support/docker/production/config/custom-environment-variables.yaml dans tout ce qui commence par PEERTUBE_. Ainsi je vous recommande de soit modifier et rajouter les variables d’environnement qui vont bien, soit de modifier le fichier production.yaml dans le dossier $HOME/peertube/support/docker/production/config/.

NB:

  • Pour rajouter un bloc de texte dans un fichier yaml, il suffit d’opter pour cette syntaxe :
  MA_VARIABLE: |
    mon long texte
    qui prend plusieurs lignes
  • Quelques variables qui sont utiles et manque de clareté sans le contexte :
    • PEERTUBE_TRANSCODING_ENABLED: active le transcodage. Il s’agit du support des résolutions plus faible (cela nécessite de la puissance du processeur et de l’espace disque) ;
    • PEERTUBE_INSTANCE_DESCRIPTION : la description de l’instance qu’on peut voir dans la section About de l’interface ;
    • PEERTUBE_SIGNUP_ENABLED : mis à true, on autorise les gens à se créer un compte sur la plateforme ;
  • Si vous modifiez la variable PEERTUBE_DB_USERNAME et PEERTUBE_DB_PASSWORD, n’oubliez pas tant pour le service peertube que pour celle de db

Lancer docker-compose

Lançons désormais docker-compose (le moment de vérité :D) :

user> PEERTUBE_WEBSERVER_HOSTNAME="<mon nom de domaine>" docker-compose -f support/docker/production/docker-compose.yml --project-directory . up

Si tout marche comme prévu, félicitations ! Maintenant il reste encore les sauvegardes à gérer.

Mettre en place les sauvegardes

Création du compte peertube_backup

J’utilise mon PC personnel qui va chaque jour faire une sauvegarde incrémentale tous les jours.

Dans un premier temps, il nous faut un utilisateur avec lequel on va opérer les sauvegardes régulières. Pour cela, il est préférable qu’il s’agisse d’un utilisateur autre que root ou celui qui fait tourner docker : nous allons lui fournir un système d’authentification par clé SSH sans mot de passe. C’est plus sûr.

En tant que root (renseignez les champs qui vont bien) :

root> adduser peertube_backup

Et renseignez les champs qui vont bien (dont le mot de passe).

Sur la machine de sauvegarde, en tant que root également (car cet utilisateur sera utile pour une tâche planifiée via cron, nous le verrons plus loin; attention: ne rentrez aucun mot de passe) :

root> mkdir -p ~/.ssh/
root> ssh-keygen -f ~/.ssh/id_rsa_backup_peertube
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/ssh/id_rsa_backup_peertube.
Your public key has been saved in /root/ssh/id_rsa_backup_peertube.pub.
The key fingerprint is:
…

Enfin, ajoutons la clé sur le serveur (toujours depuis la machine de sauvegardes) :

root> ssh-copy-id -i ~/.ssh/id_rsa_backup_peertube peertube_backup@<MON SERVEUR>

Enfin, tentez une connexion pour voir si elle fonctionne bien :

root> ssh -i ~/.ssh/id_rsa_backup_peertube peertube_backup@<MON SERVEUR>

Si la connexion fonctionne sans demande de mot de passe, c’est gagné ! Passons maintenant à la sauvegarde de bases de données !

Export de la base de données

Dans un premier temps, il faut ajouter le mot de passe de l’utilisateur peertube dans un fichier .pgpass dans le docker :

user> docker exec -ti peertube_postgres_1 /bin/bash
root> echo "<MON MOT DE PASSE POSTGRES>" > "${HOME}/.pgpass"
root> chmod 0600 "${HOME}/.pgpass"
root> exit

Testons que l’appel à pg_dump fonctionne bien (ne rien taper au prompt du password, patientez juste quelques secondes) :

user> docker exec peertube_postgres_1 pg_dump -U peertube -W -h localhost -F c peertube 1>/dev/null && echo "OK"
password:
OK
$

Si le message OK apparaît, c’est tout bon, on peut passer à la suite !

Maintenant ajoutons le script /etc/cron.daily/backup_sql avec ce contenu :

#!/bin/bash

SQL_BACKUP_PATH="/home/peertube_backup/backups/sql/sql-peertube.bak"

docker exec peertube_postgres_1 pg_dump -U peertube -W -h localhost -F c peertube > "$SQL_BACKUP_PATH" && chown peertube:peertube "$SQL_BACKUP_PATH"

Et ajoutons les droits d’exécution sur ce fichier (en tant que root) :

root> chmod +x /etc/cron.daily/backup_sql

Et n’oublions pas de créer le dossier pour accueillir les backups :

root> install -d -o peertube_backup -g peertube_backup /home/peertube_backup/backups/sql

Planifier les sauvegardes

Sur le serveur Peertube, en tant que root, rajouter des liens symboliques pour rendre accessibles

root> ln -s /home/peertube/peertube/docker-volume/data /home/peertube_backup/backups/data
root> ln -s /home/peertube/peertube/docker-volume/redis /home/peertube_backup/backups/redis

Maintenant sur la machine de sauvegarde, s’assurer que rsync est bien installé :

root@sauvegarde> apt install rsync

Enfin, toujours sur la machine de sauvegarde, éditer le script de backup /etc/cron.daily/backup_peertube (vous pouvez vous en inspirer, le modifier en fonction de vos besoin) :

#!/bin/bash
BACKUP_MEDIA="/media/sauvegarde"
BACKUP_DIR_BASE="${BACKUP_MEDIA}/peertube"
MAX_RETENTION=60

# Handle any error while backuping, so we send mails to alert
# Inspired from: https://stackoverflow.com/a/185900
error() {
  local parent_lineno="$1"
  local message="$2"
  local code="${3:-1}"
  local mail
  if [[ -n "$message" ]] ; then
    mail="Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
  else
    mail="Error on or near line ${parent_lineno}; exiting with status ${code}"
  fi
  echo "${mail}" | mail -s "Peertube daily backup alert" <MY EMAIL ADDRESS>
}

trap 'error ${LINENO}' ERR

# Ensure the media for backups is mounted
if ! grep -qs "${BACKUP_MEDIA}" /proc/mounts; then
  mount "${BACKUP_MEDIA}"
fi

# Remove oldest backup
rm -rf "${BACKUP_DIR_BASE}/backup.${MAX_RETENTION}"
for i in $(eval echo {"${MAX_RETENTION}"..2}); do
  source="${BACKUP_DIR_BASE}/backup.$((${i} - 1))"
  if [ -d "${source}" ]; then
    mv "${source}" "${BACKUP_DIR_BASE}/backup.${i}"
  fi
done

NEW_BACKUP="${BACKUP_DIR_BASE}/backup.0"

if [ -d "${NEW_BACKUP}" ]; then
  cp -al "${NEW_BACKUP}" "${BACKUP_DIR_BASE}/backup.1"
fi

for folder in data sql redis; do
  rsync -e 'ssh -i /root/.ssh/id_rsa_backup_peertube' -av --delete "peertube_backup@<MY SERVEUR>:~/backups/${folder}/" "${NEW_BACKUP}/${folder}"
done

Important :

  • Pensez bien à remplacer l’email et surtout à adapter la variable BACKUP_MEDIA

NB :

  • Pour en savoir plus sur le fonctionnement du script, je vous invite à lire cet article en anglais (duquel je me suis inspiré) ;
  • dans le script ci-dessus, je m’envoie un mail en cas d’erreur de backup. Pour cela, j’utilise ssmtp, qui permet d’envoyer simplement des mails en s’authentifiant auprès d’un fournisseur (d’un serveur SMTP plus techniquement). La doc d’Ubuntu-fr explique comment faire très simplement.

Comme précédemment pour l’autre script cron, changer les droits sur ce fichier :

root@sauvegarde> chmod +x /etc/cron.daily/backup_peertube

Et de créer le répertoire qui contiendra vos sauvegardes (le chemin est à adapter) :

root@sauvegarde> mkdir /media/sauvegarde/peertube

Florent F.

Florent F.
Ingénieur en informatique, libriste et zététicien.

Sophismes - La Généralisation Abusive

CaractéristiqueLa généralisation abusive survient quand on tire une conclusion d’une population non représentative (trop petite, trop spé...… Continue reading