rescriptum · an answer written for this machine
FR
Sur cette page

Configuration

Des variables d’environnement — et, en option, un fichier d’où les lire, dans l’une de deux formes. Il n’y a pas de ligne de commande à se tromper, et les variables sont toute la configuration : les deux formats de fichier règlent exactement les mêmes choses sous exactement les mêmes règles, donc rien de ce qu’on écrit dans un fichier ne peut signifier quelque chose que l’environnement ne dirait pas.

Les variables

VariableDéfautSignification
RESCRIPTUM_CONFIGnon définiLire les valeurs par défaut depuis ce fichier TOML — voir plus bas
RESCRIPTUM_ENV_FILEnon définiLire les valeurs par défaut depuis ce fichier CLÉ=valeur — voir plus bas
RESCRIPTUM_STOREfilesfiles (un répertoire) ou sqlite (une base)
RESCRIPTUM_ANSWERS_DIR/srv/answersRépertoire des documents de réponse
RESCRIPTUM_DB_PATH/srv/answers.dbChemin de la base, quand RESCRIPTUM_STORE=sqlite
RESCRIPTUM_LISTEN_ADDR0.0.0.0:8000Adresse d’écoute. :0 choisit un port libre, et celui qui est bindé est affiché
RESCRIPTUM_WORKERSnombre de CPUThreads du runtime asynchrone. Pas une limite de concurrence
RESCRIPTUM_MAX_CONNECTIONS2048Connexions en vol avant délestage en 503
RESCRIPTUM_TIMEOUT_SECS10Délai de lecture des en-têtes et échéance de la connexion entière
RESCRIPTUM_ANSWER_TOKENnon définiJeton exigé par l’endpoint de réponse. Non défini = ouvert
RESCRIPTUM_ADMIN_ADDRnon définiListener de l’API d’administration. Non défini = API désactivée
RESCRIPTUM_ADMIN_TOKENnon définiJeton d’administration, 16+ caractères. Obligatoire avec RESCRIPTUM_ADMIN_ADDR
RESCRIPTUM_CAPTURE_DIRnon définiEnregistre les corps de requête ici. Non défini = pas de capture
RESCRIPTUM_LOGallall, problems ou off — voir plus bas
RESCRIPTUM_LOG_FILEnon définiUn fichier où ajouter, ou stdout / stderr. Non défini = stderr
RESCRIPTUM_MEDIA_DIRnon définiImages d’installation. Non défini = pas de média et pas de listener média
RESCRIPTUM_MEDIA_ADDR0.0.0.0:8001Le listener média, quand un répertoire de médias existe
RESCRIPTUM_MEDIA_TIMEOUT_SECS600Échéance du transfert entier. Volontairement pas les 10 s du point de réponse
RESCRIPTUM_MEDIA_MAX_CONNECTIONS16Transferts simultanés. Bas exprès : chacun retient son jeton des minutes durant
RESCRIPTUM_PUBLIC_HOSTdéduitL’hôte que nomment les URL générées. Un hôte, jamais une URL
RESCRIPTUM_BOOT_ALLOWnon définiCIDR clients autorisés à récupérer les médias. Non défini = quiconque atteint le port
RESCRIPTUM_BOOT_DIRnon définiChargeurs et menus, distribués en TFTP. Non défini = pas de TFTP du tout
RESCRIPTUM_TFTP_ADDR0.0.0.0:69Le listener TFTP, ou off pour aucun. Le port 69 est privilégié ; voir RESCRIPTUM_USER
RESCRIPTUM_TFTP_PORT_RANGEnon définiLes ports depuis lesquels un transfert répond, en premier-dernier. Un transfert TFTP quitte le port 69 aussitôt — le serveur répond depuis un port neuf et le client acquitte vers celui-là — donc un pare-feu n’autorisant que 69 jette l’acquittement, et la machine semble s’être désintéressée. Épinglez la plage pour pouvoir l’ouvrir. Non définie, le noyau choisit
RESCRIPTUM_TFTP_BLKSIZE1468Le plus grand bloc TFTP accepté. 1468 remplit exactement un chemin de 1500 octets — 1468 de charge, 4 TFTP, 8 UDP, 20 IP — donc un tag VLAN ou un tunnel rend la trame trop grande et une ROM PXE s’arrête en général sans rien dire. À baisser (1400, ou 512) quand un démarrage cale au premier bloc
RESCRIPTUM_BOOT_TIMEOUT_SECS15Secondes avant que le menu ne retombe sur le disque local
RESCRIPTUM_BOOT_UNCLAIMEDmenuCe que reçoit une machine qu’aucune réponse ne revendique. local la rend à son firmware, ce qui inverse le sens d’un fichier de réponse : présent veut dire installe celle-ci plutôt que laisse celle-ci tranquille
RESCRIPTUM_INSTALLED_TOKENnon définiLe jeton du [post-installation-webhook] de Proxmox. Défini, POST /installed existe et retire la revendication d’installation d’une machine quand elle signale sa réussite. Non défini, il n’y a pas d’endpoint
RESCRIPTUM_BOOT_LOGOintégréUn PNG à afficher derrière le menu
RESCRIPTUM_BOOT_TITLEintégréLa barre de titre du menu
RESCRIPTUM_USER / _GROUPnon définiBasculer dessus après avoir lié. L’ordre inverse échoue au déploiement

/srv est l’endroit où la norme de hiérarchie des fichiers range les données servies par le système, ce qu’est précisément un répertoire de réponses. Les deux valeurs par défaut y vivent, pour qu’un rescriptum lancé sans rien fasse quelque chose de plausible sur n’importe quel hôte Linux. Rien ne crée le répertoire pour vous, et le serveur le signale au démarrage s’il manque.

Journalisation

Une ligne par événement, sur stderr par défaut. Deux réglages, parce que les deux questions sont différentes.

QuoiRESCRIPTUM_LOG :

ValeurGarde
all (défaut)chaque requête, plus le démarrage, les avertissements et les erreurs
problemsdémarrage, avertissements, erreurs, et seulement les requêtes qui n’ont pas abouti
off / nonerien du tout

Une réponse réussie fait une ligne, et à treize mille requêtes par seconde c’est la seule chose ici qui ait du volume. problems est ce que vous voulez quand un déploiement devient routinier et que le disque, lui, ne l’est pas. Tout le reste est peu volumineux et diagnostique, donc conservé dans les deux cas.

Une requête qui n’a jamais atteint de statut — une connexion expirée en plein corps — compte comme un problème. Une valeur non reconnue retombe sur all avec un avertissement : une faute de frappe ne doit pas être la raison pour laquelle personne ne voit pourquoi un déploiement a échoué. Le niveau est nommé dans la ligne de démarrage (log=problems), donc un log vide s’explique lui-même.

RESCRIPTUM_LOG_FILE :

ValeurVa vers
non définie, ou stderrstderr, ce que lit un superviseur
stdoutstdout
toute autre valeurce fichier, en ajout ; les répertoires parents sont créés

Un fichier impossible à ouvrir est une erreur de démarrage, pas un repli sur stderr — ce serait une surprise silencieuse découverte bien plus tard. Une écriture qui échoue une fois le serveur lancé est abandonnée : un serveur de provisioning qui mourrait parce que son disque de logs est plein ferait échouer toutes les installations en cours pour signaler qu’il ne peut pas signaler quelque chose.

La rotation vous incombe. Sous systemd il n’y a rien à faire, le log part dans le journal ; avec un fichier, pointez logrotate dessus avec copytruncate.

Le fichier TOML

RESCRIPTUM_CONFIG nomme un fichier en TOML qui règle les mêmes variables, dans une forme faite pour être lue. C’est celui vers lequel se tourner quand une personne édite le fichier à la main — sur un NAS, dans File Station ou via SMB — c’est-à-dire exactement là où RESCRIPTUM_ANSWERS_DIR=… sur chaque ligne se lit mal, et où le mot « environnement » envoie chercher un shell qui n’existe pas.

# /etc/rescriptum.toml   (chmod 600, appartenant à root)
answers_dir = "/srv/answers"
listen_addr = "0.0.0.0:8000"
log         = "problems"          # all | problems | off

[store]
kind    = "sqlite"
db_path = "/srv/answers.db"

[server]
workers         = 2
max_connections = 2048
timeout_secs    = 10

[admin]
addr  = "127.0.0.1:8001"
token = "…"

[answer]
token       = "…"
capture_dir = "/var/lib/rescriptum/captures"
$ RESCRIPTUM_CONFIG=/etc/rescriptum.toml rescriptum
2026-08-29T12:42:02Z - reading configuration defaults from /etc/rescriptum.toml (8 set)

Toutes les règles du fichier d’environnement valent ici aussi : jamais découvert, seulement nommé (il n’y a pas de ./rescriptum.toml) ; l’environnement réel gagne ; et un fichier demandé et illisible est une erreur de démarrage, jamais un avertissement.

Placez-le hors du répertoire de réponses. Tout .toml servable à la racine de ce répertoire est un document réponse, et ce format partage l’extension — un fichier de configuration déposé là est signalé par check comme une réponse mal placée, et migrate propose de le déplacer. /etc est le foyer évident ; sur une installation empaquetée, le paquet en choisit un.

Les noms

Le préfixe disparaît et les tables font le regroupement. Rien d’autre ne change : chaque ligne ci-dessous est la variable du même nom, et rescriptum config affiche les deux orthographes.

Dans le fichierVariable
answers_dirRESCRIPTUM_ANSWERS_DIR
listen_addrRESCRIPTUM_LISTEN_ADDR
log, log_fileRESCRIPTUM_LOG, RESCRIPTUM_LOG_FILE
public_hostRESCRIPTUM_PUBLIC_HOST
user, groupRESCRIPTUM_USER, RESCRIPTUM_GROUP
store.kind, store.db_pathRESCRIPTUM_STORE, RESCRIPTUM_DB_PATH
server.workers, server.max_connections, server.timeout_secsRESCRIPTUM_WORKERS, RESCRIPTUM_MAX_CONNECTIONS, RESCRIPTUM_TIMEOUT_SECS
admin.addr, admin.tokenRESCRIPTUM_ADMIN_ADDR, RESCRIPTUM_ADMIN_TOKEN
answer.token, answer.capture_dirRESCRIPTUM_ANSWER_TOKEN, RESCRIPTUM_CAPTURE_DIR
media.dir, media.addr, media.timeout_secs, media.max_connectionsles quatre RESCRIPTUM_MEDIA_*
boot.dir, boot.allow, boot.unclaimed, boot.timeout_secs, boot.logo, boot.titleles six RESCRIPTUM_BOOT_*
tftp.addr, tftp.port_range, tftp.blksizeles trois RESCRIPTUM_TFTP_*
installed.tokenRESCRIPTUM_INSTALLED_TOKEN

Le format

N’importe quel scalaire TOMLun nombre peut s’écrire en nombre (workers = 2) ou en chaîne ; les deux arrivent au serveur comme le même réglage
Un commentaire #n’importe où, y compris en fin de ligne — contrairement au fichier d’environnement, qui n’a pas d’échappements et ne peut donc pas en avoir
Une valeur avec un #, un guillemet ou une espacesans problème, échappée comme TOML échappe, et relue à l’identique
""non défini — la même règle qu’une variable exportée mais vide, et c’est ce qui permet à config unset de vider une ligne au lieu de supprimer le paragraphe qui la documente
La même clé deux foisrefusée par TOML lui-même, donc le fichier ne se charge pas
Une clé que ce programme ne lit pasun avertissement la nommant : admin.tokenn est attrapé au lieu d’être ignoré
Une liste ou une table là où une valeur est attendueune erreur de démarrage : contrairement à une faute de frappe, elle visait un réglage réel, et servir la valeur par défaut alors que le fichier dit le contraire serait silencieux
Un fichier lisible par d’autresun avertissement avec son mode, parce qu’il peut contenir admin.token

Les avertissements nomment les clés et les chemins, jamais les valeurs.

Les deux fichiers à la fois

Nommer les deux est une transition plutôt qu’un état stable : rien n’est refusé et l’ordre est annoncé au démarrage — l’environnement bat le fichier TOML, qui bat le fichier d’environnement. rescriptum config montre lequel des trois a mis chaque valeur en vigueur, et config set écrit dans le fichier TOML — celui que le serveur lit en premier, pour qu’une écriture ne puisse pas être une modification qui ne change rien en silence.

Le fichier d’environnement

RESCRIPTUM_ENV_FILE nomme un fichier contenant les mêmes variables. Il existe pour les déploiements qui n’ont nulle part où mettre un jeton — au premier chef Synology DSM 7, qui n’a pas de systemd. Sous systemd, EnvironmentFile= fait déjà cela et vous n’en avez pas besoin.

# /etc/rescriptum.env   (chmod 600, appartenant à root)
RESCRIPTUM_STORE=sqlite
RESCRIPTUM_DB_PATH=/srv/answers.db
RESCRIPTUM_ADMIN_ADDR=127.0.0.1:8001
RESCRIPTUM_ADMIN_TOKEN=
$ RESCRIPTUM_ENV_FILE=/etc/rescriptum.env rescriptum
2026-08-24T12:42:02Z - reading configuration defaults from /etc/rescriptum.env (4 set)

Il n’est jamais découvert, seulement nommé. Il n’y a pas de ./.env. Ce binaire tourne en root : s’il ramassait un fichier dans le répertoire d’où il a été lancé, quiconque peut y écrire posséderait RESCRIPTUM_ADMIN_TOKEN — et avec lui le mot de passe root de chaque machine installée ensuite.

L’environnement réel gagne. Le fichier fournit des valeurs par défaut, donc ce qui est exporté délibérément au lancement n’est jamais écrasé en douce. Une variable exportée mais vide compte comme non définie, donc le fichier s’applique quand même.

Un fichier demandé et illisible est une erreur de démarrage, pas un avertissement. C’est tout l’intérêt : l’échec qu’il remplace est un serveur qui démarre sur ses valeurs par défaut — mauvais répertoire de réponses, pas de jeton admin — sans un mot dans le log.

Le format

CLÉ=valeur, une par ligneun export en tête est accepté, pour que le même fichier puisse aussi être sourceé
# en début de ligneun commentaire
# ailleursfait partie de la valeur. Pas de commentaires en fin de ligne : tronquer un jeton sur un # qu’il contient légitimement serait silencieux, alors qu’un commentaire atterrissant dans une valeur est bruyant
"guillemets" ou 'guillemets'les guillemets sont retirés et les espaces internes conservés ; une valeur sans guillemets est trimée
$HOME, ${x}non développés. Ce n’est pas un shell — pas de substitution, pas de lignes de continuation
la même clé deux foisune erreur de démarrage, plutôt qu’une supposition sur celle qui était voulue
une clé que ce programme ne lit pasun avertissement nommant la clé — RESCRIPTUM_ADMIN_TOKENN est donc attrapé au lieu d’être ignoré
un fichier lisible par d’autresun avertissement avec son mode, parce qu’il peut contenir le jeton admin

Les avertissements nomment les clés et les chemins, jamais les valeurs.

Le lire et le modifier

rescriptum config affiche chaque variable, sa valeur, et qui des fichiers ou de l’environnement l’y a mise — la distinction qui compte, puisque les fichiers fournissent des valeurs par défaut et que l’environnement réel l’emporte. config set modifie le fichier comme on voudrait qu’il le soit, dans l’un ou l’autre format : commentaires conservés, réglage commenté décommenté sur place plutôt que dupliqué (fichier d’environnement) ou valeur remplacée là où elle est (TOML), et refus avant toute écriture d’une modification qui laisserait un serveur incapable de démarrer. C’est documenté dans la référence de la ligne de commande, et c’est ce que l’application DSM pilote dessous.

Valeurs invalides

CasCe qui se passe
Exportée mais vide (RESCRIPTUM_LISTEN_ADDR=)traitée comme non définie — une valeur vide est une erreur, pas une instruction
Uniquement des espacespareil, et les valeurs sont trimées
Un nombre nul ou impossible à parserretombe sur la valeur par défaut, plutôt que de démarrer un serveur qui accepte des connexions sans jamais répondre
RESCRIPTUM_STORE avec toute autre valeurun avertissement, et files est utilisé
RESCRIPTUM_ENV_FILE ou RESCRIPTUM_CONFIG nommant un fichier absent, illisible ou malforméune erreur de démarrage
Un réglage TOML recevant une liste ou une tableune erreur de démarrage, contrairement à une clé mal orthographiée, qui avertit
RESCRIPTUM_STORE=sqlite sur un binaire construit sans la featureune erreur au démarrage

Erreurs de démarrage

Celles-ci arrêtent le serveur au lieu d’avertir, parce que démarrer quand même serait pire :

ConditionPourquoi c’est fatal
RESCRIPTUM_ADMIN_ADDR défini avec RESCRIPTUM_STORE autre que sqlitedeux façons de changer la même configuration, en concurrence
RESCRIPTUM_ADMIN_ADDR défini sans RESCRIPTUM_ADMIN_TOKENune API ouverte qui réécrit les identifiants root
RESCRIPTUM_ADMIN_TOKEN de moins de 16 caractèresassez court pour être deviné
L’adresse d’écoute ne peut pas être bindéerien à faire
Le store ne peut pas être ouvertrien à servir
RESCRIPTUM_MEDIA_ADDR défini sans RESCRIPTUM_MEDIA_DIRun listener sans rien à servir
RESCRIPTUM_MEDIA_ADDR égal à l’adresse de réponse ou d’administrationle second bind perd, et lequel dépend de l’ordre de démarrage
RESCRIPTUM_PUBLIC_HOST portant un schéma, un port ou un cheminil est écrit dans les URL de deux listeners ; un port dans la valeur épingle chaque script généré sur l’un d’eux
RESCRIPTUM_TFTP_ADDR défini sans RESCRIPTUM_BOOT_DIRun listener sans chargeur à distribuer
Le répertoire de démarrage ne peut pas être résoluchaque contrôle de chemin s’y compare
RESCRIPTUM_USER nomme un compte inexistantrien à devenir

Avertissements de démarrage

Ceux-ci sont affichés et le serveur continue :

ConditionLigne
Répertoire de réponses absentwarning: … does not exist yet — every request will 404 until it does
Le chemin existe mais n’est pas un répertoirewarning: … is not a directory — every request will 404 until it is
Répertoire de réponses présent mais illisiblewarning: … cannot be read: … — every request will 404 until that is fixed. La cause la plus probable est un serveur tournant sous un utilisateur qui n’est pas le propriétaire du répertoire
API d’administration hors boucle localewarning: the admin API is not bound to loopback — …
RESCRIPTUM_ANSWER_TOKEN de moins de 16 caractèresun avertissement, pas une erreur — refuser de démarrer laisserait un parc incapable de s’installer
Tout problème dans le jeu de réponsesune ligne warning: chacun, le même jeu que signale check
RESCRIPTUM_PUBLIC_HOST non définiLa réponse de la table de routage, ou l’unique adresse d’interface s’il n’y a pas de route par défaut. Journalisé dans les deux cas, en avertissement nommant les autres adresses s’il y en a. Un hôte derrière du NAT se trompe toujours en silence
TFTP ne peut pas se lierwarning: cannot bind TFTP on … le seul listener dont l’échec de liaison n’est pas fatal. Le port 69 est le seul port privilégié de la conception, donc le seul bind qui puisse échouer pour quelque chose que personne n’a configuré ; les réponses sont le produit, et mourir ferait échouer toutes les installations en cours pour signaler qu’un second port n’a pas pu être ouvert. boot check sort en non-zéro et le message nomme les façons d’obtenir le port
Répertoire de médias absent ou illisibleune ligne warning: media: … — un parc ne doit jamais être incapable de s’installer parce qu’une image est bizarre

Options de compilation

FeatureDéfautEffet
sqliteactivéeLe store SQLite et l’API d’administration
bootactivéeLe catalogue de médias, le lecteur ISO et le listener média

Mesuré sur ARMv7 (gnueabihf, plancher glibc 2.17), les quatre d’affilée le 2026-08-29. Remesurez plutôt que de citer ces chiffres : ils ont bougé d’environ 375 Ko quand cette cible est passée de musl à glibc, et le jeu qu’ils remplacent ici avait dérivé d’environ 200 Ko.

BuildOctets
les deux (défaut)2 813 712
sqlite seule2 557 592
boot seule1 649 048
aucune1 392 544

Limites fixes

Non configurables, et délibérément :

LimiteValeur
Corps de requête1 Moendpoint de réponse — un Content-Length invraisemblable est refusé depuis l’en-tête
Taille d’un document256 KoPUT de l’API d’administration
Requêtes capturées1000 capturescomptées depuis le répertoire au démarrage, donc un redémarrage ne repart pas de zéro
Échecs d’administration avant blocage5 en 60 sle blocage double jusqu’à un maximum de 900 s
Adresses suivies par le garde-fou4096pour qu’il ne puisse pas être transformé en fuite mémoire
Filet de rechargement du listing1 sforce une relecture même quand le mtime du répertoire semble inchangé
Mis à jour le Modifier cette page