Variables d'environnement : application, serveur et base de données
Sovrium lit sa configuration d'infrastructure dans les variables d'environnement, jamais dans le schéma de l'application. Le schéma décrit votre application ; l'environnement décrit la machine qui l'exécute. Définissez les variables dans un fichier .env à côté de votre configuration, ou dans l'environnement de votre hébergeur.
Tout est optionnel. sovrium start app.yaml démarre sans configuration, avec SQLite embarqué, un stockage de fichiers local et une clé de chiffrement que l'application génère elle-même au premier démarrage. La seule variable qui mérite une décision avant un déploiement est SOVRIUM_ENCRYPTION_KEY — voir Secrets.
Les variables de stockage, d'IA, d'e-mail, de MCP, d'éco et d'observabilité sont traitées sur Variables d'environnement : services.
# .env
PORT=3000
BASE_URL=https://monapp.example.com
NODE_ENV=production
TRUSTED_PROXY_HOPS=1
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
SOVRIUM_ENCRYPTION_KEY=<64 caractères hexadécimaux>C'est une configuration de déploiement complète — un seul secret, pas deux. AUTH_SECRET est optionnel et dérive de la clé de chiffrement ; ne le définissez que si vous voulez le fixer séparément.
Application et serveur
| Variable | Par défaut | Description |
|---|---|---|
APP_SCHEMA |
— | Schéma de l'application en JSON en ligne, en YAML en ligne ou sous forme d'URL distante. Alternative au chemin de fichier passé à sovrium start. |
PORT |
3000 |
Port d'écoute (1–65535). |
HOSTNAME |
localhost |
Interface réseau d'écoute. |
BASE_URL |
http://localhost:PORT |
Origine publique canonique. Utilisée pour les rappels d'authentification, les liens des e-mails et les URL d'émetteur OAuth. |
NODE_ENV |
non définie | Environnement d'exécution. À placer sur production sur toute instance déployée — voir ci-dessous. |
TRUSTED_PROXY_HOPS |
0 |
Nombre de reverse proxies placés devant l'application (0–10). À définir dès que quelque chose s'interpose entre Internet et Sovrium — voir ci-dessous. |
Pourquoi NODE_ENV=production compte
C'est NODE_ENV=production qui active la mise en cache immuable des assets à empreinte de contenu. Avec cette valeur, les fragments d'îlots hachés sont servis en Cache-Control: public, max-age=31536000, immutable et les autres assets statiques obtiennent un cache d'une heure. Sans elle, chaque asset repart en no-store, no-cache, must-revalidate et le navigateur retélécharge tout le bundle à chaque vue de page — environ vingt fois plus de requêtes par page pour des octets identiques.
La sécurité du transport ne dépend pas de NODE_ENV. Les cookies sécurisés et l'application du CSRF sont décidés par la posture d'écoute : une BASE_URL ou un HOSTNAME non-loopback les force, une écoute en loopback les assouplit pour que http://localhost fonctionne en développement. Définissez une vraie BASE_URL en production et la posture sécurisée suit.
Reverse proxy en amont
Les limites de débit, les garde-fous anti-spam et les compteurs d'abus doivent savoir de quel client provient une requête. Quand Sovrium écoute directement sur un port, il s'agit simplement de celui qui a ouvert la connexion. Derrière un proxy, chaque requête arrive du proxy, et l'adresse réelle du client est transportée dans un en-tête de transfert.
Un client peut aussi envoyer cet en-tête lui-même. Les proxies ajoutent à X-Forwarded-For au lieu de le remplacer : ce que le client a fourni reste donc en tête de liste, et seules les entrées de fin ont été écrites par l'infrastructure que vous maîtrisez. TRUSTED_PROXY_HOPS indique à Sovrium combien d'entrées de fin croire. Tant que la variable n'est pas définie, aucun en-tête de transfert n'est cru.
| Déploiement | Valeur |
|---|---|
sovrium start écoutant directement sur un port |
0 |
| Derrière un seul proxy — Caddy, nginx ou un routeur PaaS | 1 |
| Cloudflare devant votre propre proxy | 2 |
# .env — un seul reverse proxy devant l'application
TRUSTED_PROXY_HOPS=1Laisser la variable non définie sur un déploiement derrière proxy est sûr, mais grossier : chaque visiteur se résout à l'adresse du proxy lui-même, tous partagent donc un seul budget de limite de débit et la rafale d'un seul visiteur peut brider tout le monde. La première requête qui arrive avec un en-tête de transfert émet un avertissement unique nommant cette variable.
Le cas à éviter est de la définir plus haut que le nombre de proxies réellement en place. Le compteur remonte d'autant d'entrées depuis la fin de la chaîne : une valeur gonflée atteint donc des entrées écrites par le client — ce qui lui permet de choisir son propre seau de limitation et d'échapper entièrement aux limites. Ne comptez que les proxies que vous exploitez.
Répertoire de données
Les artefacts d'exécution vivent sous un répertoire unique, pour qu'une racine de projet neuve reste propre.
| Variable | Par défaut | Description |
|---|---|---|
SOVRIUM_DATA_DIR |
./.sovrium |
Répertoire de base des artefacts générés à l'exécution. Résolu en chemin absolu. |
SOVRIUM_LOCK_DIR |
répertoire de données | Répertoire du fichier de verrou du serveur (PID et empreinte de la configuration). |
.sovrium/
database.db # SQLite par défaut — DATABASE_URL remplace
encryption-key # secret racine propre à l'installation — SOVRIUM_ENCRYPTION_KEY remplace
lock # PID du serveur + empreinte de config — SOVRIUM_LOCK_DIR remplace
storage/ # fichiers téléversés en local — STORAGE_LOCAL_DIRECTORY remplaceSOVRIUM_DATA_DIR ne déplace que l'emplacement de repli. Chaque artefact garde sa propre variable de remplacement, et celle-ci l'emporte toujours.
Base de données
| Variable | Par défaut | Description |
|---|---|---|
DATABASE_URL |
non définie (SQLite) | Chaîne de connexion. Le schéma d'URL sélectionne le moteur — voir ci-dessous. |
DATABASE_POOL_MAX |
10 |
Taille du pool de connexions PostgreSQL. Ignorée par SQLite. |
DATABASE_URL est discriminée par son schéma d'URL, et Sovrium échoue bruyamment au démarrage sur toute valeur qu'il ne reconnaît pas :
| Valeur | Moteur |
|---|---|
| non définie ou vide | SQLite dans <répertoire de données>/database.db — le défaut sans configuration |
postgresql://user:pass@host:5432/db |
PostgreSQL (postgres:// est également accepté) |
file:./data/app.db, sqlite:./app.db, :memory: |
SQLite à ce chemin (:memory: est éphémère) |
Un chemin de fichier nu est rejeté — préfixez-le par file:. Voir Infrastructure de base de données pour les différences entre dialectes.
Mettre à niveau les colonnes d'horodatage (PostgreSQL uniquement)
Un champ created-at, updated-at ou deleted-at que vous déclarez explicitement crée désormais une colonne timestamptz — le type que Sovrium a toujours utilisé pour les colonnes équivalentes qu'il ajoute pour vous. Les colonnes créées par une version antérieure restent en timestamp sans fuseau, et Sovrium ne les réécrira pas en silence.
| Variable | Par défaut | Description |
|---|---|---|
DATABASE_TIMESTAMPTZ_MIGRATION |
désactivée | Mettez on pour convertir ces colonnes en timestamptz au prochain démarrage. |
DATABASE_TIMESTAMPTZ_MIGRATION_ACK_NON_UTC |
désactivée | Mettez 1 pour autoriser la conversion quand le fuseau de la base de données n'est pas UTC. |
Tant que la migration est désactivée, chaque démarrage journalise un avertissement par colonne concernée et ne change rien — les applications existantes se mettent à niveau exactement comme avant. Les deux types de colonne se sérialisent à l'identique à travers l'API : la laisser désactivée indéfiniment est sans risque.
L'activer réécrit chaque table concernée et pose un verrou exclusif pendant toute l'opération : sur une grande table, traitez-la comme une fenêtre de maintenance. La conversion préserve chaque instant enregistré, à condition que le fuseau de votre base de données soit resté le même pendant toute la vie des données.
Si ce fuseau n'est pas UTC, le démarrage s'interrompt avec une erreur nommant le fuseau observé. Deux situations qu'il ne peut pas vérifier lui-même deviennent alors possibles : un fuseau modifié à un moment du passé (les lignes écrites de part et d'autre du changement désignent des instants différents, et il n'est plus possible de savoir lesquelles sont lesquelles), et l'heure répétée à la fin de l'heure d'été (une valeur dans cette heure est ambiguë, et jusqu'à une heure de lignes par an peut se décaler d'une heure). Mettez DATABASE_TIMESTAMPTZ_MIGRATION_ACK_NON_UTC=1 pour continuer malgré tout, ou épinglez d'abord la base de données sur UTC.
Secrets
Deux secrets protègent une application Sovrium : une clé de chiffrement pour les identifiants stockés, et un secret de signature pour les sessions. Aucun n'a besoin d'être défini — l'application se les provisionne elle-même — mais l'endroit où elle tourne décide si cela suffit.
| Variable | Par défaut | Description |
|---|---|---|
SOVRIUM_ENCRYPTION_KEY |
générée dans <répertoire>/encryption-key |
Clé maîtresse de chiffrement des identifiants stockés au repos (AES-256-GCM), et racine dont dérive le secret d'authentification. |
AUTH_SECRET |
dérivé de la clé de chiffrement | Signe les cookies de session, les jetons et les URL signées. 16 caractères minimum si vous le définissez ; la valeur générée fait 64 hexadécimaux. |
Pour les définir vous-même, sovrium secret generate imprime des lignes .env prêtes à coller sur la sortie standard et ne les écrit jamais sur disque :
sovrium secret generate # les deux
sovrium secret generate auth # AUTH_SECRET seulement
sovrium secret generate encryption # SOVRIUM_ENCRYPTION_KEY seulementComment la clé de chiffrement est résolue
SOVRIUM_ENCRYPTION_KEYsi elle est définie — elle l'emporte, et rien n'est écrit sur disque.<répertoire de données>/encryption-key— la clé que cette installation a générée lors d'un démarrage précédent.- Sinon 256 bits frais, écrits dans
<répertoire de données>/encryption-keyen mode0600.
Si le répertoire de données ne peut pas être écrit, l'application refuse de démarrer plutôt que de tourner sur une clé qu'elle oubliera. Chaque démarrage indique laquelle des trois voies a été empruntée :
✓ Encryption key: from SOVRIUM_ENCRYPTION_KEY
✓ Encryption key: from /var/lib/sovrium/encryption-key
✓ Encryption key: generated at /var/lib/sovrium/encryption-keyVoir generated at — et non from — sur un redémarrage signifie que la clé précédente a disparu et que tout ce qu'elle chiffrait est désormais illisible.
Quand la définir vous-même
La clé générée se place à côté de la base SQLite qu'elle protège : sur un disque persistant, les deux vivent et meurent ensemble et rien n'est jamais laissé en plan. Le développement local et un déploiement SQLite sur un seul serveur n'ont besoin d'aucune clé.
Définissez SOVRIUM_ENCRYPTION_KEY explicitement — ou laissez le générateur de secrets de votre plateforme la fournir — dès que la clé et les données qu'elle protège n'ont pas le même destin :
- une
DATABASE_URLexterne sur un hébergeur dont le système de fichiers est réinitialisé à chaque déploiement ou redémarrage : Heroku, Render, Scalingo,docker runsans volume ; - tout déploiement où le répertoire de données n'est pas un volume persistant.
Là, la base survit à la clé qui l'a chiffrée : chaque jeton de connexion stocké devient illisible au redémarrage suivant — et de nouveau à celui d'après. Sovrium le dit au démarrage quand il reconnaît cette configuration :
⚠ Encryption key was generated on this boot while DATABASE_URL points at an external database
— set SOVRIUM_ENCRYPTION_KEY to a fixed value so stored connection tokens survive a restartRetirer la variable d'une installation existante
Une installation qui fournit déjà SOVRIUM_ENCRYPTION_KEY ne peut pas simplement la retirer : le démarrage suivant ne trouverait aucun fichier de clé, en générerait une, et abandonnerait tout ce que l'ancienne clé chiffrait. Lancez d'abord sovrium secret adopt — la commande écrit la clé que le processus possède déjà dans le fichier que le serveur lit, si bien que retirer la variable ne change rien.
Sauvegardez la clé avec la base de données. Un identifiant stocké, chiffré avec une clé que vous n'avez plus, est irrécupérable — les utilisateurs concernés doivent se reconnecter. Gardez <répertoire de données>/encryption-key dans vos sauvegardes, ou la valeur dans le coffre à secrets de votre plateforme. Définir ou faire tourner AUTH_SECRET déconnecte toutes les sessions actives.
Utilisateur administrateur par défaut
Crée un administrateur au premier démarrage. L'e-mail et le mot de passe doivent tous deux être définis pour que la création ait lieu.
| Variable | Par défaut | Description |
|---|---|---|
AUTH_ADMIN_EMAIL |
— | Adresse e-mail de l'administrateur créé. |
AUTH_ADMIN_PASSWORD |
— | Mot de passe de ce compte. 8 caractères minimum. |
AUTH_ADMIN_NAME |
Admin |
Nom affiché. |
AUTH_ADMIN_ROLE |
admin |
Rôle attribué au compte créé. |
sovrium admin create <email> fait le même travail de façon interactive, sans placer de mot de passe dans l'environnement.
Fournisseurs OAuth
Chaque fournisseur configuré dans le schéma d'authentification lit une paire d'identifiants. Remplacez {PROVIDER} par le nom du fournisseur en majuscules — GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, et ainsi de suite. Google, GitHub, Microsoft, Slack, GitLab et Facebook sont pris en charge. Les URL de rappel sont dérivées de BASE_URL : elle doit donc être correcte avant qu'OAuth ne fonctionne.
Suite
- Variables d'environnement : services — stockage, IA, e-mail, MCP, éco, observabilité.
- Fichiers de configuration — ce qui relève du schéma à la place.
- Présentation de l'authentification — comment
AUTH_SECRETet les identifiants OAuth sont utilisés. - Durcissement de la sécurité — le socle de sécurité au déploiement.
Dernière mise à jour 28 août 2026
Cette documentation a été rédigée avec de l'IA : des erreurs ou du contenu obsolète sont donc possibles. Sovrium est en bêta. Les contributions et corrections sont les bienvenues.