Installation & déploiement
Enkadenn se déploie avec Docker Compose : un conteneur PostgreSQL (db) et l'application monolithe (app, API + interface web) servie sur le port 3000.
Prérequis
- Docker et Docker Compose v2
- Un accès au dépôt du projet
Chemin recommandé : l'installateur
./install.sh
Le script pose les questions dont la réponse ne se devine pas, écrit le fichier .env, lance la pile, attend que l'API réponde, puis crée le premier compte d'administration. Il est bilingue : la langue est devinée depuis la locale du système, puis confirmée à la première question. ENKADENN_LANGUE=en ./install.sh (ou =fr) l'impose sans la demander.
Ce qu'il vérifie avant d'écrire quoi que ce soit :
- que Docker répond et que Compose v2 est présent ;
- qu'une source d'aléa existe —
openssl, ou/dev/urandomà défaut. Découvrir à mi-chemin qu'on ne sait pas produire de secret laisserait un.envà moitié écrit ; - que le port demandé n'est pas déjà pris sur la machine ;
- qu'aucune base de données de ce projet n'existe déjà. PostgreSQL ne lit
POSTGRES_PASSWORDqu'à la création de son volume : sur une base existante, un mot de passe neuf serait écrit dans.envsans jamais être appliqué, et l'application ne pourrait plus s'y connecter. Le script propose alors de ressaisir le mot de passe d'origine, ou de détruire la base en connaissance de cause.
Si un .env existe déjà, trois issues sont offertes : le compléter (vos valeurs sont conservées, seules les variables manquantes sont ajoutées — c'est le cas d'une mise à jour), le remplacer avec sauvegarde horodatée, ou renoncer.
L'installateur est interactif. Pour une installation automatisée, écrivez .env vous-même à partir de .env.example, puis docker compose up --build -d.
À la main
cp .env.example .env
# Secret de session, obligatoire :
echo "JWT_SECRET=$(openssl rand -hex 32)" >> .env
docker compose up -d --build
Au démarrage, le conteneur app applique automatiquement les migrations de base de données, puis lance l'API. L'application est ensuite disponible sur http://localhost:3000.

Variables
| Variable | Rôle |
|---|---|
JWT_SECRET | Obligatoire. Signe les sessions et dérive la cl é de chiffrement des secrets stockés. Le changer déconnecte tout le monde et rend illisible le mot de passe SMTP enregistré en base. |
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB | Identifiants de la base. Le mot de passe n'est lu qu'à la création du volume. |
APP_URL | Adresse publique, préfixant tous les liens envoyés (joueur, activation, mot de passe). Réglable ensuite depuis la console d'instance, qui prime. |
PORT | Port exposé (défaut 3000). |
TRUSTED_PROXIES | Nombre de proxys inverses devant l'API. À renseigner dès qu'il y en a un, sinon le plafonnement compte l'IP du proxy pour tout le monde. |
SECRETS_KEY | Clé de chiffrement des secrets stockés. Absente, elle est dérivée de JWT_SECRET ; la définir séparément permet de faire tourner JWT_SECRET sans rendre ces secrets illisibles. |
RETENTION_DAYS | Purge automatique des exercices archivés après N jours (0 = désactivé). |
AUDIT_RETENTION_DAYS / SIGNUP_RETENTION_DAYS | Rétention du journal d'audit (730 j) et des demandes d'inscription traitées (90 j). |
DOCS_URL | Adresse d'un wiki public, liée depuis la page de connexion. Vide = aucun lien. |
WEBRTC_ICE_SERVERS | Serveurs ICE/TURN pour les appels vocaux, en JSON. Vide = aucune donnée ne sort de l'instance, la liaison ne s'établit qu'au sein d'un même réseau. |
Ne committez jamais votre fichier .env. Il porte vos secrets, et l'installateur lui applique les permissions 600.
Le premier compte d'administration
Une base neuve ne contient aucun compte, et l'inscription publique est fermée par défaut : sans cette étape, personne ne peut se connecter. install.sh s'en charge. À la main :
printf '%s' 'votre-mot-de-passe' | docker compose exec -T app \
node apps/api/dist/scripts/amorcer-instance.js \
--email=admin@mon-domaine.fr --nom='Prénom Nom'
Le mot de passe se transmet par un tube, jamais en argument : la ligne de commande d'un processus est lisible par tout utilisateur de la machine, et resterait dans l'historique du shell.
La commande refuse de s'exécuter si l'instance a déjà un administrateur — elle sert à amorcer, pas à s'ajouter à une instance en service. Les comptes suivants se créent depuis la console d'instance, qui trace qui les a créés.
L'administration d'instance exige un second facteur, et l'exigence est immédiate : prévoyez l'appareil qui le portera dès la première connexion.
Envoi de courriel
Sans relais, l'instance fonctionne mais n'envoie rien : ni invitation, ni activation de compte, ni réinitialisation de mot de passe. Les comptes doivent alors être créés à la main et les accès transmis autrement.
Deux façons de le déclarer, et elles ne se valent pas :
- depuis la console d'instance — recommandé : le mot de passe est chiffré avant d'être stocké ;
- dans
.env(SMTP_HOST,SMTP_PORT,SMTP_SECURE,SMTP_USER,SMTP_PASSWORD,MAIL_FROM) — le mot de passe y est en clair, lisible par quiconque peut faire undocker inspect. C'est le chemin d'amorçage, que l'installateur propose. Dès qu'un hôte est saisi en console, ses réglages priment en bloc sur ceux de l'environnement.
Le produit refuse une session SMTP en clair, même quand le relais l'accepte : STARTTLS est exigé (TLS 1.2 minimum). Un relais interne sur le port 25 sans STARTTLS ne conviendra pas.
L'authentification, elle, est facultative : un relais qui reconnaît ses clients à leur adresse réseau fonctionne sans identifiants.
Jeu de données de démonstration
Deux organisations cloisonnées, leurs comptes et un exercice prêt à jouer :
docker compose exec app node_modules/.bin/ts-node apps/api/prisma/seed.ts
Le mot de passe de ces comptes est publié dans le dépôt. Réservez ce jeu à un poste de test, jamais à une instance accessible.
Mettre à jour
Après avoir récupéré une nouvelle version du code :
docker compose up -d --build
Les nouvelles migrations sont appliquées au redémarrage. Si la nouvelle version attend des variables absentes de votre .env, relancez ./install.sh et choisissez compléter : vos valeurs sont conservées, seules les manquantes sont ajoutées.
Sauvegarder
Les données vivent dans deux volumes, et sauvegarder l'un sans l'autre laisse une restauration incomplète : la base (db_data) et les fichiers téléversés (uploads_data — pièces jointes de la GED, avatars, logos, écrits sur disque et non stockés en base).
# Base
docker compose exec -T db pg_dump -U enkadenn enkadenn > sauvegarde.sql
# Fichiers téléversés (le nom du volume est préfixé par celui du projet Compose)
docker run --rm -v enkadenn_uploads_data:/data -v "$PWD":/sortie alpine \
tar czf /sortie/televerses.tar.gz -C /data .
docker compose down -v détruit la base et les fichiers téléversés, sans confirmation.