Suivi du Grand Oral

Guides d’utilisation / Guide d’installation

Installer le suivi du Grand Oral sur les serveurs de l’établissement

L’archive des sources contient le logiciel et de quoi l’installer. Une fois le site installé, l’établissement est seul maître de ses données : elles restent sur son serveur, et l’éditeur n’y a aucun accès.

Comptez une demi-heure, surtout pour répondre aux questions du script d’installation. Vous n’avez pas besoin de connaître Python. Il vous faut un accès sudo à la machine, et savoir vous servir d’un terminal.

L’archive à installer

Ce guide est aussi dans l’archive des sources, à côté du script d’installation. Vous pouvez télécharger l’archive après avoir lu et accepté la licence.

Lire la licence et télécharger

grandoral-1.4.0.tar.gz, 664 Ko.
SHA-256 a3ddb9c8eee867c3264dc698591909087820364cd9d60b09d4c108cf9e541a09

Ce que le site fait, et ce qu’il ne fait pas

Le site remplace la navette papier du carnet de bord entre l’élève et ses deux professeurs encadrants. Chaque élève y prépare les deux questions de son grand oral, palier par palier. Les deux premiers paliers servent à trouver les questions. Les suivants servent à choisir chaque question et à la préparer, jusqu’à son grand oral blanc.

  • Il n’envoie aucun message et ne collecte aucune adresse de messagerie. L’administrateur imprime les identifiants et les remet sur papier.
  • Il ne se connecte à rien. Pas de service tiers, pas d’appel sortant, pas de statistiques d’audience, pas de cookie publicitaire.
  • Rien n’est jamais écrasé. Chaque enregistrement d’un palier crée une version, et tout l’historique reste consultable.

Une fois installé, le site sert lui-même les trois guides d’usage, un par rôle, à l’adresse /guides. Ils se lisent sans compte et s’impriment tels quels.

Ce qu’il faut avant de commencer

ÉlémentDétail
ÉlémentSystèmeDétailDebian 12, le système du serveur de l’éditeur, ou toute distribution avec systemd qui fournit les versions de Python et de SQLite ci-dessous. Ni Debian 11 ni Ubuntu 22.04 ne les fournissent
ÉlémentPythonDétail3.11 ou plus récent, avec le module venv
ÉlémentSQLiteDétail3.35 ou plus récent : la version liée à Python, qui crée la base. L’installateur la vérifie avant d’écrire quoi que ce soit
ÉlémentPaquetsDétailpython3-venv, sqlite3, nginx
ÉlémentRéseauDétailun accès sortant, le temps d’installer les dépendances Python
ÉlémentNom de domaineDétailun nom qui pointe déjà sur la machine, par exemple grandoral.mon-etablissement.fr. Le nom seul, sans chemin ni port : une adresse copiée depuis le navigateur est ramenée à ce nom, et un nom accentué s’écrit sous sa forme xn--. Le site occupe tout ce nom : prenez un sous-domaine si le domaine principal sert déjà à autre chose
ÉlémentCertificatDétailcertbot pour le HTTPS, installé après le site
sudo apt update
sudo apt install python3-venv sqlite3 nginx certbot python3-certbot-nginx

Le site n’a besoin ni d’un serveur de base de données, ni d’un moteur de recherche, ni d’un conteneur : il tient dans un processus Python et un fichier SQLite. Une machine modeste suffit largement pour un lycée.

Les informations à préparer

Le script les demande une par une. Rassemblez-les avant, pour ne pas avoir à le relancer.

Ces valeurs remplissent les pages légales de votre espace, que le site publie sans authentification. Un visiteur, un parent ou un élève doit pouvoir savoir à quoi il consent avant de saisir un identifiant. Tant qu’une valeur est vide, la page affiche « à renseigner ».

InformationExemple
InformationNom affiché de l’établissementExempleLycée Jean Moulin
InformationIdentité complèteExempledénomination, numéro UAI, adresse postale, téléphone
InformationStatutExempleétablissement public ou établissement privé
InformationDirecteur ou directrice de la publicationExemplele chef d’établissement, nom et fonction
InformationHébergeur du siteExemplevous-même le plus souvent : le service informatique, avec son adresse
InformationContact pour l’exercice des droitsExemplel’adresse à laquelle un élève ou sa famille écrit
InformationDélégué à la protection des donnéesExemplele DPD de l’académie, ou celui de l’organisme de gestion
InformationAnnée scolaireExemple2026-2027, ou rien pour qu’elle se déduise de la date
InformationFuseau horaireExempleEurope/Paris par défaut, ou celui de l’établissement : Indian/Reunion, America/Martinique

Le fuseau horaire sert à afficher les heures dans les pages. La base, elle, les écrit en temps universel. La touche Entrée garde le fuseau de la métropole.

Le statut décide de la base légale annoncée. Un établissement public traite ces données pour une mission d’intérêt public. Un établissement privé les traite au titre du contrat de scolarisation. Les droits ouverts ne sont pas les mêmes : il n’y a pas de droit à la portabilité pour une mission d’intérêt public. Le script refuse donc toute autre valeur.

L’établissement est responsable du traitement. L’éditeur du logiciel n’est ni responsable de traitement, ni sous-traitant : il vous fournit un logiciel, et ne reçoit aucune demande sur vos données.

Installer

tar -xzf grandoral-1.4.0.tar.gz
cd grandoral-1.4.0
sudo bash installer.sh

Le script :

  1. vérifie que la machine a ce qu’il faut ;
  2. pose ses questions, puis les récapitule avant d’écrire quoi que ce soit ;
  3. crée le compte système du service, sans droit de connexion ;
  4. copie les sources dans /opt/grandoral, crée leur environnement Python et installe les dépendances ;
  5. écrit la configuration dans /etc/grandoral.env, avec une clé de signature tirée au sort, lisible par root seul ;
  6. crée la base de données et applique le schéma ;
  7. installe le service systemd et le démarre ;
  8. installe la sauvegarde quotidienne, à 2 h 30, avec une rotation de 21 jours ;
  9. installe le site nginx et le recharge ;
  10. crée le compte administrateur, et vous en demande le mot de passe.

Vous pouvez le relancer sans risque : il garde ce qui est déjà en place, et ne réécrit jamais /etc/grandoral.env.

Chaque question propose une valeur par défaut entre crochets : la touche Entrée l’accepte. Pour installer sans questions, par exemple depuis un outil de déploiement, passez les mêmes valeurs par l’environnement :

sudo GO_DOMAINE=grandoral.mon-etablissement.fr \
     GO_NOM_ETABLISSEMENT="Lycée Jean Moulin" \
     GO_ETABLISSEMENT_STATUT=public \
     SANS_QUESTIONS=1 bash installer.sh

Les versions des dépendances

L’archive contient deux listes de dépendances, et un verrou pour chacune. requirements.txt nomme les bibliothèques dont le site a besoin, chacune entre deux bornes. C’est cette liste que le script installe : pip prend la dernière version permise par chaque borne. Une mise à jour du logiciel apporte donc aussi les correctifs de ces bibliothèques, sans rien faire de plus.

requirements.lock fige ces versions, dépendances indirectes comprises : ce sont les versions exactes avec lesquelles l’éditeur a testé cette livraison, avec l’empreinte de chaque fichier attendu. Le script ne l’installe que si vous le demandez :

sudo AVEC_VERROU=1 bash installer.sh

pip refuse alors tout fichier dont l’empreinte diffère : un index détourné ou un miroir mal tenu est arrêté là. Cela permet de reproduire exactement l’installation de l’éditeur, par exemple pour trouver quelle mise à jour de bibliothèque a cassé quelque chose. Attention : sur une plateforme pour laquelle l’index ne publie rien d’installable, cette forme échoue, alors que les bornes trouvent une version.

requirements-dev.txt et requirements-dev.lock font de même pour les outils de vérification : la suite de tests et les deux analyseurs. Le second contient aussi les dépendances de production, et se suffit à lui-même. Le script n’installe ni l’un ni l’autre : le service n’exécute ni pytest ni ruff.

Après l’installation

1. Le certificat HTTPS

sudo certbot --nginx -d grandoral.mon-etablissement.fr

Le site envoie lui-même l’en-tête Strict-Transport-Security : il ne peut pas être servi sans certificat. Le renouvellement est ensuite automatique.

Servez le site sous ce seul nom, celui que l’installateur écrit dans GO_URL_PUBLIQUE. Le site refuse un formulaire qui dit venir d’un autre site. Or un navigateur ancien ne dit d’où vient son formulaire que par son adresse : envoyé sous un autre nom, ce formulaire serait refusé aussi.

2. Ouvrir l’année

Connectez-vous avec le compte administrateur, puis suivez le tableau de bord : le calendrier, les professeurs de spécialité, l’import des élèves depuis un tableur, et l’impression des identifiants à distribuer. Le guide de l’administrateur, à l’adresse /guides/administrateur, décrit chaque opération.

3. Relire les pages légales

Ouvrez /legal et relisez les quatre pages. Elles décrivent ce que le logiciel fait vraiment : les cookies qu’il pose, les durées de conservation, qui a accès à quoi. Vérifiez surtout qu’il ne reste aucune mention « à renseigner » : ce serait une déclaration incomplète, publiée sous votre responsabilité.

Pour corriger une coordonnée, modifiez /etc/grandoral.env, puis :

sudo systemctl restart grandoral

4. Les sauvegardes

Le service fait une sauvegarde chaque nuit dans /var/backups/grandoral, et garde celles des trois dernières semaines. Ces archives contiennent des données personnelles de mineurs : elles sont en mode 600, dans un dossier en

  1. GRANDORAL_RETENTION allonge cette durée, jamais au-delà d’un an : c’est

la durée annoncée par la page de protection des données de votre espace. Au même terme, le script efface aussi les copies que le site dépose à côté de la base avant une purge ou une restauration.

Deux choses restent à décider. Tant que ce n’est pas fait, le script vous le rappelle dans son journal :

  • le chiffrement. Posez GRANDORAL_CLE_AGE dans l’environnement du service de sauvegarde : les archives sont alors chiffrées avec age, et rien n’est gardé en clair. Si la clé ne permet pas de chiffrer, la sauvegarde échoue sans rien garder, et le journal le dit. Gardez la clé privée hors de ce serveur, avec les secrets de l’établissement : sinon, le chiffrement ne protège de rien ;
  • la copie hors machine. Posez GRANDORAL_MIROIR, une destination rsync locale ou distante. Une sauvegarde qui reste sur le serveur disparaît avec lui, le jour même où l’on en a besoin. La destination garde ce qu’elle reçoit : faites-y effacer les copies avant un an, sinon la page de protection des données serait fausse.

Posez ces deux réglages dans une surcharge de l’unité de sauvegarde. Cette unité interdit au script le réseau, et tout dossier autre que les siens. La surcharge qui déclare le miroir doit donc aussi ouvrir ce qu’il demande : le réseau pour une machine distante, son dossier pour un disque local. systemd ajoute ces lignes à celles de l’unité, il ne les remplace pas. Sans elles, la copie est refusée chaque nuit, et le journal dit quelle ligne manque.

sudo systemctl edit grandoral-sauvegarde.service
# [Service]
# Environment=GRANDORAL_CLE_AGE=age1...
# Environment=GRANDORAL_MIROIR=sauvegardes@autre-machine:/grandoral
# RestrictAddressFamilies=AF_INET AF_INET6

Pour un disque local, les deux dernières lignes deviennent :

Environment=GRANDORAL_MIROIR=/mnt/sauvegardes/grandoral
ReadWritePaths=/mnt/sauvegardes/grandoral

Un miroir distant se connecte avec une clé sans phrase de passe, qui appartient au compte du service, grandoral par défaut. La machine distante doit être connue d’avance : sous l’unité, ssh ne peut ni demander s’il faut lui faire confiance, ni l’ajouter aux machines connues. Faites ceci une fois, avant la première nuit :

sudo -u grandoral ssh-keygen -t ed25519 -N ''
sudo -u grandoral ssh-copy-id sauvegardes@autre-machine   # ou la clé publique déposée à la main
sudo -u grandoral ssh sauvegardes@autre-machine true      # accepte la clé d'hôte
sudo systemctl start grandoral-sauvegarde.service         # éprouve la surcharge

La page Données de l’espace d’administration produit aussi une archive complète, avec la base et les dépôts des élèves : rangez-la avec les archives de l’établissement. Prenez-en une avant toute opération de fin d’année.

systemctl list-timers grandoral-sauvegarde.timer
sudo systemctl start grandoral-sauvegarde.service    # sauvegarde immédiate
journalctl -u grandoral-sauvegarde.service -n 20

Exploiter au quotidien

systemctl status grandoral            # le service tourne-t-il
journalctl -u grandoral -f            # le journal, en direct
sudo systemctl restart grandoral      # après une modification de la configuration

Le journal du service ne contient aucune donnée personnelle : ni nom, ni contenu du carnet, ni adresse de visiteur. Le journal des accès de nginx garde les adresses tronquées, comme l’annonce la page de protection des données de votre espace. Une demande en http:// fait exception. Certbot écrit son renvoi vers https:// dans un bloc à part, sans journal propre. nginx écrit donc ce renvoi dans son journal général, /var/log/nginx/access.log, avec l’adresse entière. La page de protection des données le dit aussi. Le journal des erreurs de nginx, lui, garde l’adresse entière : la page ne l’annonce que pour une requête que le serveur n’a pas pu traiter. Rien de courant n’y est donc écrit : le site installé y écrit les refus de débit sous le seuil du journal, et refuse les fichiers cachés par un return 404, qui n’y écrit rien. Avec un deny à la place, chaque sonde de robot y serait inscrite.

Où sont les choses

ÉlémentEmplacement
ÉlémentSourcesEmplacement/opt/grandoral
ÉlémentBase de donnéesEmplacement/opt/grandoral/data/grandoral.db
ÉlémentDépôts des élèves, cartes mentales et enregistrementsEmplacement/opt/grandoral/uploads
ÉlémentConfiguration et secretsEmplacement/etc/grandoral.env, root, mode 600
ÉlémentServiceEmplacement/etc/systemd/system/grandoral.service
ÉlémentSite nginxEmplacement/etc/nginx/sites-available/grandoral.conf, ou /etc/nginx/conf.d/grandoral.conf sans sites-available
ÉlémentSauvegardesEmplacement/var/backups/grandoral

Vérifier ce qui est installé

L’archive contient la suite de tests du logiciel, celle que l’éditeur fait passer avant chaque livraison, et la configuration des trois outils qui la lancent. Elle sert à deux moments : après une installation, pour vérifier que le site fonctionne bien sur votre machine, et après une modification de votre part, pour voir ce qu’elle a changé ailleurs.

Elle n’est pas installée par défaut : le service n’en a pas besoin, et ses outils n’ont rien à faire en production. Installez-les à part, dans le même environnement :

cd /opt/grandoral
sudo -u grandoral env HOME=/opt/grandoral \
  .venv/bin/pip install --require-hashes -r requirements-dev.lock
sudo -u grandoral env HOME=/opt/grandoral bash verifier.sh

Ici, on installe le verrou, contrairement à l’installation du site : la suite tourne ainsi avec les versions qui l’ont vue passer. C’est important : un pytest plus récent que celui qui a été testé peut la faire échouer sur un avertissement de dépréciation. Vous chercheriez alors dans votre installation une cause qui n’y est pas.

verifier.sh lance les trois contrôles, du moins coûteux au plus coûteux : la recherche de fautes, celle des types, puis la suite elle-même. Comptez quelques minutes. Aucun des trois ne touche à votre base ni à vos dépôts : la suite crée sa propre base, dans un dossier temporaire qu’elle efface.

Certains tests s’annoncent écartés, avec leur raison : ils portent sur le site de présentation de l’éditeur et sur ses propres serveurs, que l’archive ne contient pas. C’est normal.

Redonner un mot de passe administrateur

Si le mot de passe administrateur est perdu, redéfinissez-le depuis la machine :

cd /opt/grandoral
sudo -u grandoral env GO_DB_PATH=/opt/grandoral/data/grandoral.db \
  .venv/bin/python -m app.cli creer-admin --identifiant admin

Cette commande n’écrit que dans la base, et n’a pas besoin des secrets du service. Elle demande le mot de passe deux fois, sans l’afficher : il ne passe ni par un fichier, ni par l’historique du terminal.

Les mots de passe des élèves et des professeurs, eux, se redonnent depuis le site : l’administrateur remet un mot de passe provisoire depuis la liste concernée. Si l’on connaît encore son mot de passe, administrateur compris, on le change depuis le site, par l’entrée Mot de passe du menu qui porte son nom, en haut de chaque page, sans passer par la machine.

Mettre à jour

Savoir quand

Ce site n’envoie aucun message et ne demande aucune adresse, pas même pour télécharger les sources. Personne ne sait donc que vous utilisez ce logiciel, et personne ne vous préviendra si une faille y est trouvée, ou dans une bibliothèque qu’il utilise. L’éditeur publie ses avis de sécurité à ces deux adresses :

  • la page des avis, https://grandoral.scientic.org/securite ;
  • le flux qui les annonce, https://grandoral.scientic.org/securite/flux.atom.

Abonnez à ce flux le lecteur de flux de l’établissement, ou l’outil qui reçoit déjà vos alertes techniques. Un avis dit ce qui est touché, dans quelle version c’est corrigé, et ce qu’il faut faire. C’est votre seul moyen d’être prévenu : une mise à jour n’arrive que si vous la lancez.

Installer la nouvelle version

Une mise à jour, c’est la même archive, dans une version plus récente :

tar -xzf grandoral-1.4.0.tar.gz
cd grandoral-1.4.0
sudo bash installer.sh

Le script arrête le service, remplace les sources et met les dépendances à jour. Il sauvegarde ensuite la base et les dépôts avec l’unité de sauvegarde nocturne, chiffrement et copie hors machine compris si vous les avez posés. Puis il applique les migrations manquantes et redémarre le service. Le site est indisponible pendant la mise à jour. Le script ne réécrit pas /etc/grandoral.env. Il ne modifie la base que par ses migrations, une fois la base sauvegardée.

Si la sauvegarde échoue, la mise à jour s’arrête, avant la migration. Quelle que soit la cause d’une interruption, le service reste arrêté et le script le dit. Corrigez ce qu’il indique, puis relancez sudo bash installer.sh : il reprend la mise à jour.

Fin d’année scolaire

La page Données de l’espace d’administration a une rubrique Purger une année scolaire. Elle efface les comptes des élèves d’une année, tout leur carnet, et le journal des actions sensibles antérieur à la fin de cette année. Elle montre d’abord ce qui serait effacé, puis demande de retaper l’année. Une sauvegarde complète est déposée à côté de la base juste avant l’effacement.

Vous pouvez aussi faire la même opération depuis le serveur :

cd /opt/grandoral
sudo -u grandoral env GO_DB_PATH=/opt/grandoral/data/grandoral.db \
  .venv/bin/python -m app.cli purger-annee --annee 2025-2026 --simulation

La simulation n’écrit rien : elle affiche le décompte. Sans --simulation, la commande demande de retaper l’année avant d’effacer.

Prévenez les élèves assez tôt, pour que ceux qui veulent garder leur carnet le téléchargent, par l’entrée Télécharger mon carnet du menu qui porte leur nom. Après l’effacement, il sera impossible de le leur remettre. Les comptes des professeurs, celui de l’administrateur et le calendrier ne sont pas effacés.

Licence, sources, garantie

Le logiciel est distribué sous GNU Affero General Public License, version 3 ou ultérieure (AGPL-3.0-or-later). Son texte complet est le fichier LICENCE de l’archive. Vous pouvez étudier le logiciel, l’installer, le modifier et le redistribuer à ces conditions, sans garantie. L’archive contient le code source complet de ce qui tournera chez vous, sauf le site de présentation de l’éditeur, qui ne relève pas de cette licence et ne vous concerne pas.

Vous n’avez besoin d’aucun abonnement, d’aucune déclaration et d’aucun contrat pour installer et utiliser ce logiciel chez vous.

La licence vous impose une obligation dès que le site est en ligne : vos élèves et vos professeurs l’utilisent par le réseau, et ils doivent pouvoir en obtenir le code source, même si vous l’avez modifié. Le site s’en charge tout seul : la page Code source, en bas de chaque page, propose une archive construite à partir des fichiers installés sur votre serveur. Vous n’avez rien à faire, sinon laisser cette page accessible.

Si vous modifiez le logiciel, vos modifications restent sous la même licence, et c’est votre version qui se télécharge depuis votre serveur. Vous n’avez pas à les publier ailleurs, ni à les envoyer à l’éditeur. L’archive contient de quoi les vérifier : la suite de tests, sa configuration et le script qui lance les trois contrôles, décrits plus haut.

Revenir aux guides