# Installation de PeerTube avec Docker : Alternative éthique à YouTube pour associations et collectifs

## **Table des matières**
1. [Introduction](#introduction)
2. [Prérequis](#préquis)
3. [Architecture](#architecture)
4. [Préparation](#préparation)
5. [Installation](#installation)
6. [Traefik](#traefik)
7. [Configuration PeerTube](#peertube-config)
8. [Sécurité](#securite)
9. [Transcodage](#transcodage)
10. [Utilisateurs](#utilisateurs)
11. [Stockage](#stockage)
12. [Maintenance](#maintenance)
13. [Troubleshooting](#troubleshooting)

---

## **1. Introduction**

### **Qu’est-ce que PeerTube ?**
PeerTube est une plateforme vidéo open source, décentralisée et alternative à YouTube. Elle utilise le protocole WebRTC pour le partage de vidéos en peer-to-peer.

**Avantages :**
- Pas de publicité
- Hébergement autonome
- Partage de bande passante P2P
- Contrôle total des données
- Fédération via ActivityPub
- Streaming HLS adaptatif

### **À qui s’adresse ce guide ?**
Ce tutoriel permet de déployer une instance PeerTube en production avec :
- Nom de domaine personnalisé
- HTTPS automatique (Let’s Encrypt)
- Sécurité renforcée (firewall, fail2ban)
- Inscriptions avec validation email
- Architecture scalable

---

## **2. Prérequis**

### **Matériel recommandé**
| Configuration         | Valeur recommandée         |
|----------------------|----------------------------|
| CPU                  | 4 cœurs (8 threads idéal)  |
| RAM                  | 8 Go minimum               |
| Stockage             | 200 Go SSD/NVMe            |
| Bande passante       | Upload ≥ 20 Mbps           |

### **Logiciels requis**
- OS : Debian 12 (Bookworm)
- Docker et Docker Compose
- Accès DNS (OVH, Cloudflare, etc.)
- IP publique fixe ou dynamique
- Compte email SMTP (Gmail, SendGrid, etc.)

---

## **3. Architecture**

### **Schéma d’architecture et de fonctionnement**

```
┌───────────────────────────────────────────────────────────────────────────────┐
│                                                                               │
│   ┌─────────────┐    ┌─────────────┐    ┌───────────────────────────────────┐ │
│   │             │    │             │    │                                   │ │
│   │  Visiteur   │───▶│   Traefik   │───▶│         PeerTube                  │ │
│   │             │    │             │    │                                   │ │
│   └─────────────┘    └─────────────┘    └───────────────────────────────────┘ │
│          ▲                                      │                             │
│          │                                      ▼                             │
│   ┌──────┴──────┐                        ┌─────────────────────┐              │
│   │   Internet  │                        │   PostgreSQL/Redis   │             │
│   └────────────┘                        └─────────────────────┘               │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
```

**Flux de données :**
1. Le visiteur accède à `peertube.mondomaine.fr` (HTTPS).
2. Traefik gère le certificat SSL et redirige vers PeerTube.
3. PeerTube lit/écrit dans PostgreSQL et Redis.
4. Les vidéos sont stockées en HLS pour le streaming adaptatif.

---

## **4. Préparation du serveur**

### **Structure des dossiers**
```bash
mkdir -p ~/peertube/{traefik/{dynamic,acme},config}
cd ~/peertube
```
**Permissions critiques :**
```bash
touch traefik/acme/acme.json
chmod 600 traefik/acme/acme.json
```

---

## **5. Installation avec Docker Compose**

### **Fichier `docker-compose.yml`**
```yaml
services:
  traefik:
    image: traefik:v3.3
    container_name: traefik
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - ./traefik/dynamic:/etc/traefik/dynamic:ro
      - ./traefik/acme:/acme
    networks:
      - traefik-proxy

  peertube:
    image: chocobozzz/peertube:v8.0.0-trixie
    container_name: peertube
    restart: always
    volumes:
      - data:/data
      - ./config:/config
    depends_on:
      - postgres
      - redis
      - traefik
    networks:
      - traefik-proxy
      - peertube
    environment:
      - PEERTUBE_WEBSERVER_HOSTNAME=peertube.mondomaine.fr
      - PEERTUBE_WEBSERVER_HTTPS=true
      - PEERTUBE_WEBSERVER_PORT=443
      - PEERTUBE_DB_HOSTNAME=postgres
      - PEERTUBE_DB_USERNAME=peertube
      - PEERTUBE_DB_PASSWORD=peertube
      - PEERTUBE_REDIS_HOSTNAME=redis
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.peertube.entrypoints=http"
      - "traefik.http.routers.peertube.rule=Host(`peertube.mondomaine.fr`)"
      - "traefik.http.routers.peertube-secure.entrypoints=https"
      - "traefik.http.routers.peertube-secure.rule=Host(`peertube.mondomaine.fr`)"
      - "traefik.http.routers.peertube-secure.tls=true"
      - "traefik.http.routers.peertube-secure.tls.certresolver=letsencrypt"
      - "traefik.http.services.peertube.loadbalancer.server.port=9000"
      - "traefik.docker.network=traefik-proxy"

  postgres:
    image: postgres:16-alpine
    container_name: peertube-postgres
    restart: always
    environment:
      POSTGRES_USER: peertube
      POSTGRES_PASSWORD: peertube
      POSTGRES_DB: peertube
    volumes:
      - db:/var/lib/postgresql/data
    networks:
      - peertube

  redis:
    image: redis:7-alpine
    container_name: peertube-redis
    restart: always
    volumes:
      - redis:/data
    networks:
      - peertube

networks:
  traefik-proxy:
    name: traefik-proxy
    driver: bridge
  peertube:
    name: peertube
    driver: bridge

volumes:
  data:
  db:
  redis:
```

**⚠️ Remplacez `peertube.mondomaine.fr` et les mots de passe par vos valeurs.**

---

## **6. Configuration Traefik**

### **Fichier `traefik/traefik.yml`**
```yaml
api:
  dashboard: true
  insecure: false

entryPoints:
  http:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: https
          scheme: https
          permanent: true
  https:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-proxy
  file:
    directory: /etc/traefik/dynamic
    watch: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@mondomaine.fr
      storage: /acme/acme.json
      httpChallenge:
        entryPoint: http
```

---

## **7. Configuration PeerTube**

### **Fichier `config/production.yaml`**
```yaml
listen:
  hostname: '0.0.0.0'
  port: 9000

webserver:
  https: true
  hostname: 'peertube.mondomaine.fr'
  port: 443

database:
  hostname: 'postgres'
  port: 5432
  suffix: ''
  username: 'peertube'
  password: 'peertube'
  pool:
    max: 5

redis:
  hostname: 'redis'
  port: 6379
  auth: null
  db: 0

smtp:
  hostname: smtp.gmail.com
  port: 465
  username: votre-email@gmail.com
  password: "votre-mot-de-passe-app"
  tls: true
  disable_starttls: false
  ca_file: null
  from_address: votre-email@gmail.com

signup:
  enabled: true
  limit: 10
  requires_email_verification: true

video_transcoding:
  enabled: true
  web_videos:
    enabled: false
  hls:
    enabled: true

secrets:
  peertube: "REMPLACER_PAR_VOTRE_SECRET"
```

**⚠️ Générez un secret sécurisé :**
```bash
openssl rand -hex 32
```

---

## **8. Sécurité**

### **UFW Firewall**
```bash
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw --force enable
```

### **Fail2ban**
```bash
sudo apt install -y fail2ban
sudo nano /etc/fail2ban/jail.local
```
```ini
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = ufw
backend = systemd

[sshd]
enabled = true
port = 22
maxretry = 3
bantime = 7200
```

---

## **9. Transcodage vidéo**

### **Configuration recommandée**
```yaml
video_transcoding:
  enabled: true
  web_videos:
    enabled: false
  hls:
    enabled: true
```
**Résolutions conseillées :**
- 480p, 720p, 1080p

---

## **10. Gestion des utilisateurs**

### **Activer les inscriptions**
- Via l’interface admin ou `production.yaml` :
```yaml
signup:
  enabled: true
  requires_email_verification: true
```

---

## **11. Stockage et backup**

### **Script de backup automatique**
```bash
#!/bin/bash
DATE=$(date +%Y-%m-%d_%H:%M:%S)
LOG="/var/log/peertube-backup.log"
SOURCE="/home/user/peertube/"
DEST="/mnt/backup-disk/peertube_backup/"

echo "[$DATE] Début backup PeerTube" >> $LOG
docker compose stop peertube postgres redis
rsync -av --delete "$SOURCE" "$DEST" >> $LOG 2>&1
docker compose start peertube postgres redis
```

---

## **12. Maintenance**

### **Commandes utiles**
```bash
docker compose logs -f peertube
docker compose restart peertube
docker system prune -a
```

---

## **13. Troubleshooting**

| Problème                     | Solution                                                                 |
|------------------------------|--------------------------------------------------------------------------|
| Conteneur ne démarre pas     | `docker compose logs peertube`                                           |
| Certificat SSL non obtenu     | Vérifier DNS, ports, permissions `acme.json`                              |
| Pas de bouton "S’inscrire"    | Vérifier `signup.enabled` dans `production.yaml`                          |
| Emails non envoyés           | Tester SMTP manuellement, vérifier mot de passe application (Gmail)      |
| Transcodage très lent        | Réduire le nombre de résolutions, surveiller CPU avec `htop`              |


## Ressources utiles

- **Documentation officielle** : [https://docs.joinpeertube.org/](https://docs.joinpeertube.org/)
- **Docker Compose** : [https://docs.docker.com/compose/](https://docs.docker.com/compose/)
- **Rsync manuel** : [https://linux.die.net/man/1/rsync](https://linux.die.net/man/1/rsync)
- **Crontab generator** : [https://crontab.guru/](https://crontab.guru/)
- **Forum PeerTube** : [https://framacolibri.org/c/peertube/](https://framacolibri.org/c/peertube/)
- **Aukfood** .[https://www.aukfood.fr/peertube-dockerise-avec-traefik-2/](https://www.aukfood.fr/peertube-dockerise-avec-traefik-2/)