Paillasse/docs/runbooks/stockage-s3.md
Adam Belkacemi 6ea7a1cc16 ajoute le stockage S3 des devoirs maison (bloc B, dernier chantier)
Dépôt de fichier en plus du texte libre pour les devoirs maison, stocké
sur Hetzner Object Storage (jamais sur le disque du serveur), masqué
côté élève tant que le bucket n'est pas configuré. Purge RGPD étendue
pour supprimer aussi les fichiers d'Object Storage. Ansible lit les
identifiants depuis un fichier que seul Adam peut créer sur le serveur
(runbook docs/runbooks/stockage-s3.md) ; le bloc B du CLAUDE.md est
maintenant complet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 09:52:15 +02:00

3 KiB

Runbook — Stockage S3 des devoirs maison

Les fichiers que les élèves joignent à leurs devoirs maison sont stockés sur Hetzner Object Storage (S3-compatible), jamais sur le disque du serveur (app/Services/Stockage/StockageTravauxEleves.php). Tant que le bucket n'est pas configuré, le bouton de dépôt de fichier reste simplement masqué côté élève (texte libre toujours disponible) — rien ne casse.

Claude ne peut ni créer le bucket ni générer les clés (CLAUDE.md : commandes et dépenses jamais par Claude). Cette étape est entièrement à faire par Adam.

1. Créer le bucket (console Hetzner)

Dans le projet Hetzner dédié à Paillasse (jamais tripoli-cloud) :

  1. Object Storage → créer un bucket, région au choix (ex. fsn1).
  2. Activer le versioning sur le bucket (un fichier écrasé reste récupérable quelques temps).
  3. Générer une paire de clés d'accès scopée à ce bucket seulement (pas une clé avec accès à tout le compte).

Vérifier les noms exacts des options dans la console/doc Hetzner au moment de le faire : l'interface peut avoir changé depuis l'écriture de ce runbook.

2. Créer le fichier de secrets sur le serveur

Sur 163.172.4.195, jamais dans Git, jamais collé dans une conversation avec Claude :

ssh paillasse
sudo mkdir -p /etc/syllabus
sudo tee /etc/syllabus/s3-paillasse.yaml > /dev/null <<'EOF'
access_key: "COLLER_LA_CLE_ICI"
secret_key: "COLLER_LE_SECRET_ICI"
bucket: "nom-du-bucket"
region: "fsn1"
endpoint: "https://fsn1.your-objectstorage.com"
EOF
sudo chmod 600 /etc/syllabus/s3-paillasse.yaml
sudo chown root:root /etc/syllabus/s3-paillasse.yaml

Adapter region/endpoint à ce que la console Hetzner affiche pour le bucket créé.

3. Déployer

Depuis le Mac :

cd ansible && script -q /dev/null ansible-playbook portail.yml -i inventory.ini

Le rôle portail (roles/portail/tasks/03-code.yml) lit ce fichier s'il existe, écrit AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_BUCKET/ AWS_DEFAULT_REGION/AWS_ENDPOINT dans .env et redémarre Horizon. S'il n'existe pas encore, ce bloc ne fait rien.

4. Vérifier

cd /var/www/portail
sudo -u www-data HOME=/tmp php8.3 artisan tinker \
  --execute="echo App\Services\Stockage\StockageTravauxEleves::disponible() ? 'ok' : 'non configure';"

Puis, en élève de test, ouvrir un devoir : le champ « Joindre un fichier » doit apparaître. Déposer un petit fichier, vérifier côté prof qu'il apparaît et se télécharge. Supprimer le compte de test ensuite.

RGPD

Un fichier déposé est supprimé d'Object Storage dès que la classe qui le contient est purgée (classes:purger-archivees, 90 jours après archivage) — voir app/Console/Commands/PurgerClassesArchivees.php.

Rotation des clés

Même logique que pour le compte de service OpenStack (runbook dédié) : régénérer les clés dans la console Hetzner, remplacer access_key/secret_key dans /etc/syllabus/s3-paillasse.yaml, redéployer (étape 3).