Cladèse documentation

Exploitation

La ligne de commande, le worker, les migrations et les sauvegardes.

La CLI#

e-learning-cli est installée dans l'image de l'API. Dans Docker, préfixez par docker compose exec api ; hors Docker, par uv run.

CommandeEffetOptions
reconcileSynchronise le dossier des médias avec la base--videos-path
list-videosListe les vidéos et leur UUID-f, --formation nom ou slug
convertConvertit des médias pour le web avec ffmpeg--glob (défaut **/*.*), --overwrite, --videos-path
transcribeTranscrit une vidéo, de façon synchrone-v UUID, -m modèle Whisper (base), -l langue, --timecodes
summary (alias resume)Génère le résumé d'une vidéo-v UUID
index-ragIndexe transcriptions, résumés et documents dans Qdrant--formation-id ou --video-id
create-adminCrée un compte administrateur ; refuse un email déjà pris--email, --password (demandé, masqué, si absent), --full-name

Les commandes de la CLI s'exécutent dans le processus, sans passer par RabbitMQ : pratique pour un traitement par lot ou pour déboguer un job qui échoue.

Le worker#

docker compose logs -f worker
docker compose up -d --scale worker=2   # deux processus, chacun avec son prefetch

Chaque processus traite jusqu'à APP_WORKER_PREFETCH jobs en parallèle. La console RabbitMQ, sur le port 15672, montre la profondeur de la file. Whisper consomme beaucoup de mémoire : augmentez le nombre de workers avec prudence.

Migrations#

Le service migrate applique alembic upgrade head à chaque docker compose up. À la main :

docker compose run --rm migrate
# hors Docker
cd e-learning-api
uv run alembic upgrade head
uv run alembic revision --autogenerate -m "description"
Passage aux comptes : les données anonymes sont supprimées La migration 007_user_credentials ajoute email, mot de passe et rôle aux utilisateurs, et supprime les anciens identifiants anonymes avec leurs notes, leur progression et leur consommation : un identifiant anonyme ne peut pas être rattaché de façon sûre à un email. Le retour arrière retire les colonnes mais ne restaure pas ces données. Lancez ./scripts/backup.sh avant la mise à jour, et renseignez APP_SECRET_KEY et APP_FIRST_ADMIN_* dans .env.

Sauvegardes#

scripts/backup.sh sauvegarde la base PostgreSQL uniquement, avec pg_dump dans le conteneur.

./scripts/backup.sh                    # créer une archive (puis rotation)
./scripts/backup.sh list               # lister
./scripts/backup.sh restore            # restaurer la plus récente
./scripts/backup.sh restore backups/e-learning-2026-08-05_120000.dump
./scripts/backup.sh prune              # garder les BACKUP_KEEP plus récentes
VariableDéfautRôle
BACKUP_DIR./backupsDossier des archives
BACKUP_KEEP7Archives conservées par prune
COMPOSE_FILE./docker-compose.ymlFichier Compose
ENV_FILE./.envFichier d'environnement

Chaque sauvegarde applique la rotation dans la foulée. Tous les jours à 2 h :

0 2 * * * cd /srv/e-learning && ./scripts/backup.sh >> /var/log/e-learning-backup.log 2>&1
Les médias ne sont pas dans l'archive Vidéos, documents, transcriptions et résumés sont des fichiers sous VIDEOS_HOST_PATH. Sauvegardez ce dossier séparément. Qdrant se reconstruit avec e-learning-cli index-rag.

Exemple avec restic, dédupliqué et chiffré, lancé après la sauvegarde de la base :

export RESTIC_REPOSITORY=/mnt/sauvegardes/e-learning   # ou sftp:, s3:, rest:…
export RESTIC_PASSWORD_FILE=/root/.restic-e-learning

restic init                                            # une seule fois
restic backup /chemin/vers/VIDEOS_HOST_PATH ./backups
restic forget --keep-daily 7 --keep-weekly 4 --prune

Diagnostic#

SymptômePiste
L'API redémarre en boucledocker compose logs api : APP_SECRET_KEY ou APP_FIRST_ADMIN_PASSWORD à leur valeur d'exemple, ou "*" dans APP_CORS_ORIGINS
Le front affiche « Impossible de joindre l'API » ou une erreur CORSNEXT_PUBLIC_API_URL injoignable depuis le navigateur, ou adresse du front absente de APP_CORS_ORIGINS (127.0.0.1 et localhost sont deux origines différentes)
La connexion web réussit mais renvoie aussitôt à l'écran de connexionCookie refusé : API en HTTP hors localhost (cookie Secure), ou front et API sur deux sites différents
Connexion refusée avec 429Cinq échecs en quinze minutes pour cet email ou cette adresse IP ; attendre, ou redémarrer l'API pour remettre le compteur à zéro
Mot de passe administrateur perduUn autre admin le réinitialise depuis Studio → Comptes, ou e-learning-cli create-admin avec un nouvel email
Une formation ajoutée sur disque n'apparaît pase-learning-cli reconcile ; vérifier les trois niveaux de dossiers
La vidéo ne se lit pasCodec non supporté : Convertir pour le web dans le studio
Statut bloqué sur processingdocker compose logs worker, état de RabbitMQ
/ready en erreurPostgreSQL arrêté ou APP_DATABASE_URL incorrecte
Téléversement refuséFichier plus gros que APP_MAX_UPLOAD_SIZE, ou limite du proxy