Ç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 queuser
(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 :
- Docker (procédure d’installation pour Debian) ;
- Git : avec la commande
sudo apt install git
; - Docker-compose (procédure d’installation) ;
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 sectionAbout
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
etPEERTUBE_DB_PASSWORD
, n’oubliez pas tant pour le servicepeertube
que pour celle dedb
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